Skip to content

Commit 0be0bc1

Browse files
committed
Update usage of material3 adaptive to be edge-to-edge
Change-Id: I481c79db77bbdd657182f5355200f63e2355f40d
1 parent 16f45c0 commit 0be0bc1

File tree

5 files changed

+92
-5
lines changed

5 files changed

+92
-5
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ dependencies {
100100
implementation(libs.androidx.navigation.compose)
101101
implementation(libs.androidx.profileinstaller)
102102
implementation(libs.androidx.tracing.ktx)
103+
implementation(libs.androidx.window.core)
103104
implementation(libs.kotlinx.coroutines.guava)
104105
implementation(libs.coil.kt)
105106

app/dependencies/prodReleaseRuntimeClasspath.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ androidx.vectordrawable:vectordrawable:1.1.0
123123
androidx.versionedparcelable:versionedparcelable:1.1.1
124124
androidx.viewpager:viewpager:1.0.0
125125
androidx.window.extensions.core:core:1.0.0
126-
androidx.window:window-core-android:1.3.0-alpha02
127-
androidx.window:window-core:1.3.0-alpha02
128-
androidx.window:window:1.3.0-alpha02
126+
androidx.window:window-core-android:1.3.0-alpha03
127+
androidx.window:window-core:1.3.0-alpha03
128+
androidx.window:window:1.3.0-alpha03
129129
androidx.work:work-runtime-ktx:2.9.0
130130
androidx.work:work-runtime:2.9.0
131131
com.caverock:androidsvg-aar:1.4

app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ internal fun NiaApp(
179179
Column(Modifier.fillMaxSize()) {
180180
// Show the top app bar on top level destinations.
181181
val destination = appState.currentTopLevelDestination
182+
val shouldShowTopAppBar = destination != null
182183
if (destination != null) {
183184
NiaTopAppBar(
184185
titleRes = destination.titleTextId,
@@ -207,6 +208,13 @@ internal fun NiaApp(
207208
duration = Short,
208209
) == ActionPerformed
209210
},
211+
modifier = if (shouldShowTopAppBar) {
212+
Modifier.consumeWindowInsets(
213+
WindowInsets.safeDrawing.only(WindowInsetsSides.Top),
214+
)
215+
} else {
216+
Modifier
217+
},
210218
)
211219
}
212220

app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,29 @@
1717
package com.google.samples.apps.nowinandroid.ui.interests2pane
1818

1919
import androidx.activity.compose.BackHandler
20+
import androidx.compose.foundation.layout.PaddingValues
21+
import androidx.compose.foundation.layout.WindowInsets
2022
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
23+
import androidx.compose.material3.adaptive.Posture
24+
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
25+
import androidx.compose.material3.adaptive.allVerticalHingeBounds
26+
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
27+
import androidx.compose.material3.adaptive.layout.HingePolicy
2128
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
2229
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
2330
import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
31+
import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
32+
import androidx.compose.material3.adaptive.layout.calculateStandardPaneScaffoldDirective
2433
import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
2534
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
35+
import androidx.compose.material3.adaptive.occludingVerticalHingeBounds
36+
import androidx.compose.material3.adaptive.separatingVerticalHingeBounds
2637
import androidx.compose.runtime.Composable
2738
import androidx.compose.runtime.LaunchedEffect
2839
import androidx.compose.runtime.getValue
40+
import androidx.compose.ui.geometry.Rect
41+
import androidx.compose.ui.unit.Dp
42+
import androidx.compose.ui.unit.dp
2943
import androidx.hilt.navigation.compose.hiltViewModel
3044
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3145
import androidx.navigation.NavGraphBuilder
@@ -34,6 +48,7 @@ import androidx.navigation.compose.NavHost
3448
import androidx.navigation.compose.composable
3549
import androidx.navigation.compose.rememberNavController
3650
import androidx.navigation.navArgument
51+
import androidx.window.core.layout.WindowWidthSizeClass
3752
import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute
3853
import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERESTS_ROUTE
3954
import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG
@@ -76,7 +91,12 @@ internal fun InterestsListDetailScreen(
7691
selectedTopicId: String?,
7792
onTopicClick: (String) -> Unit,
7893
) {
79-
val listDetailNavigator = rememberListDetailPaneScaffoldNavigator<Nothing>()
94+
val scaffoldDirective = calculateNoContentPaddingScaffoldDirective(
95+
currentWindowAdaptiveInfo(),
96+
)
97+
val listDetailNavigator = rememberListDetailPaneScaffoldNavigator<Nothing>(
98+
scaffoldDirective = scaffoldDirective,
99+
)
80100
BackHandler(listDetailNavigator.canNavigateBack()) {
81101
listDetailNavigator.navigateBack()
82102
}
@@ -116,6 +136,7 @@ internal fun InterestsListDetailScreen(
116136
}
117137
}
118138
},
139+
windowInsets = WindowInsets(0, 0, 0, 0),
119140
)
120141
LaunchedEffect(Unit) {
121142
if (selectedTopicId != null) {
@@ -132,3 +153,59 @@ private fun <T> ThreePaneScaffoldNavigator<T>.isListPaneVisible(): Boolean =
132153
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
133154
private fun <T> ThreePaneScaffoldNavigator<T>.isDetailPaneVisible(): Boolean =
134155
scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded
156+
157+
/**
158+
* This is a direct clone of [calculateStandardPaneScaffoldDirective] with the only change of
159+
* passing 0 content padding to the panes.
160+
*/
161+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
162+
private fun calculateNoContentPaddingScaffoldDirective(
163+
windowAdaptiveInfo: WindowAdaptiveInfo,
164+
verticalHingePolicy: HingePolicy = HingePolicy.AvoidSeparating,
165+
): PaneScaffoldDirective {
166+
val maxHorizontalPartitions: Int
167+
val verticalSpacerSize: Dp
168+
when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) {
169+
WindowWidthSizeClass.COMPACT -> {
170+
maxHorizontalPartitions = 1
171+
verticalSpacerSize = 0.dp
172+
}
173+
WindowWidthSizeClass.MEDIUM -> {
174+
maxHorizontalPartitions = 1
175+
verticalSpacerSize = 0.dp
176+
}
177+
else -> {
178+
maxHorizontalPartitions = 2
179+
verticalSpacerSize = 24.dp
180+
}
181+
}
182+
val maxVerticalPartitions: Int
183+
val horizontalSpacerSize: Dp
184+
185+
if (windowAdaptiveInfo.windowPosture.isTabletop) {
186+
maxVerticalPartitions = 2
187+
horizontalSpacerSize = 24.dp
188+
} else {
189+
maxVerticalPartitions = 1
190+
horizontalSpacerSize = 0.dp
191+
}
192+
193+
return PaneScaffoldDirective(
194+
PaddingValues(0.dp),
195+
maxHorizontalPartitions,
196+
verticalSpacerSize,
197+
maxVerticalPartitions,
198+
horizontalSpacerSize,
199+
getExcludedVerticalBounds(windowAdaptiveInfo.windowPosture, verticalHingePolicy),
200+
)
201+
}
202+
203+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
204+
private fun getExcludedVerticalBounds(posture: Posture, hingePolicy: HingePolicy): List<Rect> {
205+
return when (hingePolicy) {
206+
HingePolicy.AvoidSeparating -> posture.separatingVerticalHingeBounds
207+
HingePolicy.AvoidOccluding -> posture.occludingVerticalHingeBounds
208+
HingePolicy.AlwaysAvoid -> posture.allVerticalHingeBounds
209+
else -> emptyList()
210+
}
211+
}

gradle/libs.versions.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ androidxTestRules = "1.5.0"
2727
androidxTestRunner = "1.5.2"
2828
androidxTracing = "1.3.0-alpha02"
2929
androidxUiAutomator = "2.2.0"
30-
androidxWindowManager = "1.2.0"
30+
androidxWindowManager = "1.3.0-alpha03"
3131
androidxWork = "2.9.0"
3232
coil = "2.6.0"
3333
dependencyGuard = "0.4.3"
@@ -101,6 +101,7 @@ androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "
101101
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
102102
androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxUiAutomator" }
103103
androidx-tracing-ktx = { group = "androidx.tracing", name = "tracing-ktx", version.ref = "androidxTracing" }
104+
androidx-window-core = { group = "androidx.window", name = "window-core", version.ref = "androidxWindowManager" }
104105
androidx-work-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" }
105106
androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidxWork" }
106107
coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" }

0 commit comments

Comments
 (0)