1717package com.google.samples.apps.nowinandroid.ui.interests2pane
1818
1919import androidx.activity.compose.BackHandler
20+ import androidx.compose.foundation.layout.PaddingValues
21+ import androidx.compose.foundation.layout.WindowInsets
2022import 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
2128import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
2229import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
2330import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
31+ import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
32+ import androidx.compose.material3.adaptive.layout.calculateStandardPaneScaffoldDirective
2433import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
2534import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
35+ import androidx.compose.material3.adaptive.occludingVerticalHingeBounds
36+ import androidx.compose.material3.adaptive.separatingVerticalHingeBounds
2637import androidx.compose.runtime.Composable
2738import androidx.compose.runtime.LaunchedEffect
2839import 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
2943import androidx.hilt.navigation.compose.hiltViewModel
3044import androidx.lifecycle.compose.collectAsStateWithLifecycle
3145import androidx.navigation.NavGraphBuilder
@@ -34,6 +48,7 @@ import androidx.navigation.compose.NavHost
3448import androidx.navigation.compose.composable
3549import androidx.navigation.compose.rememberNavController
3650import androidx.navigation.navArgument
51+ import androidx.window.core.layout.WindowWidthSizeClass
3752import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute
3853import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERESTS_ROUTE
3954import 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 )
133154private 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+ }
0 commit comments