Skip to content

Commit bc9dfb8

Browse files
authored
update adaptive layouts samples to navigable scaffolds (#468)
* update adaptive snippets to have navigable scaffolds implementation * swap windowSizeClass.windowWidthSizeClass with windowSizeClass.isWidthAtLeastBreakpoint * update adaptive dependency to 1.1 stable
1 parent 030dddb commit bc9dfb8

File tree

3 files changed

+189
-76
lines changed

3 files changed

+189
-76
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt

Lines changed: 104 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.example.compose.snippets.adaptivelayouts
1818

1919
import android.os.Parcelable
20-
import androidx.activity.compose.BackHandler
2120
import androidx.compose.foundation.background
2221
import androidx.compose.foundation.clickable
2322
import androidx.compose.foundation.layout.Column
@@ -30,33 +29,39 @@ import androidx.compose.material3.Card
3029
import androidx.compose.material3.ListItem
3130
import androidx.compose.material3.Text
3231
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
32+
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
33+
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
3334
import androidx.compose.material3.adaptive.layout.AnimatedPane
3435
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
3536
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
37+
import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
38+
import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior
39+
import androidx.compose.material3.adaptive.navigation.NavigableListDetailPaneScaffold
40+
import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldPredictiveBackHandler
3641
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
3742
import androidx.compose.runtime.Composable
43+
import androidx.compose.runtime.rememberCoroutineScope
3844
import androidx.compose.ui.Modifier
3945
import androidx.compose.ui.graphics.Color
4046
import androidx.compose.ui.tooling.preview.Preview
4147
import androidx.compose.ui.unit.dp
4248
import androidx.compose.ui.unit.sp
49+
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_EXPANDED_LOWER_BOUND
50+
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
51+
import kotlinx.coroutines.launch
4352
import kotlinx.parcelize.Parcelize
4453

4554
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
4655
@Composable
47-
fun SampleListDetailPaneScaffoldParts() {
56+
fun SampleNavigableListDetailPaneScaffoldParts() {
4857
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part02]
49-
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
50-
51-
BackHandler(navigator.canNavigateBack()) {
52-
navigator.navigateBack()
53-
}
58+
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
59+
val scope = rememberCoroutineScope()
5460
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part02]
5561

5662
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part03]
57-
ListDetailPaneScaffold(
58-
directive = navigator.scaffoldDirective,
59-
value = navigator.scaffoldValue,
63+
NavigableListDetailPaneScaffold(
64+
navigator = scaffoldNavigator,
6065
// [START_EXCLUDE]
6166
listPane = {},
6267
detailPane = {},
@@ -65,16 +70,21 @@ fun SampleListDetailPaneScaffoldParts() {
6570
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part03]
6671

6772
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part04]
68-
ListDetailPaneScaffold(
69-
directive = navigator.scaffoldDirective,
70-
value = navigator.scaffoldValue,
73+
NavigableListDetailPaneScaffold(
74+
navigator = scaffoldNavigator,
7175
listPane = {
7276
AnimatedPane {
7377
MyList(
7478
onItemClick = { item ->
7579
// Navigate to the detail pane with the passed item
76-
navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
77-
}
80+
scope.launch {
81+
scaffoldNavigator
82+
.navigateTo(
83+
ListDetailPaneScaffoldRole.Detail,
84+
item
85+
)
86+
}
87+
},
7888
)
7989
}
8090
},
@@ -85,16 +95,14 @@ fun SampleListDetailPaneScaffoldParts() {
8595
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part04]
8696

8797
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part05]
88-
ListDetailPaneScaffold(
89-
directive = navigator.scaffoldDirective,
90-
value = navigator.scaffoldValue,
91-
listPane =
98+
NavigableListDetailPaneScaffold(
99+
navigator = scaffoldNavigator,
92100
// [START_EXCLUDE]
93-
{},
101+
listPane = {},
94102
// [END_EXCLUDE]
95103
detailPane = {
96104
AnimatedPane {
97-
navigator.currentDestination?.content?.let {
105+
scaffoldNavigator.currentDestination?.contentKey?.let {
98106
MyDetails(it)
99107
}
100108
}
@@ -106,39 +114,103 @@ fun SampleListDetailPaneScaffoldParts() {
106114
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
107115
@Preview
108116
@Composable
109-
fun SampleListDetailPaneScaffoldFull() {
110-
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
111-
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
117+
fun SampleNavigableListDetailPaneScaffoldFull() {
118+
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
119+
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
120+
val scope = rememberCoroutineScope()
112121

113-
BackHandler(navigator.canNavigateBack()) {
114-
navigator.navigateBack()
115-
}
122+
NavigableListDetailPaneScaffold(
123+
navigator = scaffoldNavigator,
124+
listPane = {
125+
AnimatedPane {
126+
MyList(
127+
onItemClick = { item ->
128+
// Navigate to the detail pane with the passed item
129+
scope.launch {
130+
scaffoldNavigator.navigateTo(
131+
ListDetailPaneScaffoldRole.Detail,
132+
item
133+
)
134+
}
135+
},
136+
)
137+
}
138+
},
139+
detailPane = {
140+
AnimatedPane {
141+
// Show the detail pane content if selected item is available
142+
scaffoldNavigator.currentDestination?.contentKey?.let {
143+
MyDetails(it)
144+
}
145+
}
146+
},
147+
)
148+
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
149+
}
150+
151+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
152+
@Composable
153+
fun SampleListDetailPaneScaffoldWithPredictiveBackFull() {
154+
// [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_with_pb_full]
155+
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
156+
val customScaffoldDirective = customPaneScaffoldDirective(currentWindowAdaptiveInfo())
157+
val scope = rememberCoroutineScope()
158+
159+
ThreePaneScaffoldPredictiveBackHandler(
160+
navigator = scaffoldNavigator,
161+
backBehavior = BackNavigationBehavior.PopUntilContentChange
162+
)
116163

117164
ListDetailPaneScaffold(
118-
directive = navigator.scaffoldDirective,
119-
value = navigator.scaffoldValue,
165+
directive = customScaffoldDirective,
166+
scaffoldState = scaffoldNavigator.scaffoldState,
120167
listPane = {
121168
AnimatedPane {
122169
MyList(
123170
onItemClick = { item ->
124171
// Navigate to the detail pane with the passed item
125-
navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
172+
scope.launch {
173+
scaffoldNavigator.navigateTo(
174+
ListDetailPaneScaffoldRole.Detail,
175+
item
176+
)
177+
}
126178
},
127179
)
128180
}
129181
},
130182
detailPane = {
131183
AnimatedPane {
132184
// Show the detail pane content if selected item is available
133-
navigator.currentDestination?.content?.let {
185+
scaffoldNavigator.currentDestination?.contentKey?.let {
134186
MyDetails(it)
135187
}
136188
}
137189
},
138190
)
139-
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
140191
}
141192

193+
fun customPaneScaffoldDirective(currentWindowAdaptiveInfo: WindowAdaptiveInfo): PaneScaffoldDirective {
194+
val horizontalPartitions = when {
195+
currentWindowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(
196+
WIDTH_DP_EXPANDED_LOWER_BOUND
197+
) -> 3
198+
currentWindowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(
199+
WIDTH_DP_MEDIUM_LOWER_BOUND
200+
) -> 2
201+
else -> 1
202+
}
203+
204+
return PaneScaffoldDirective(
205+
maxHorizontalPartitions = horizontalPartitions,
206+
horizontalPartitionSpacerSize = 16.dp,
207+
maxVerticalPartitions = 1,
208+
verticalPartitionSpacerSize = 8.dp,
209+
defaultPanePreferredWidth = 320.dp,
210+
excludedBounds = emptyList()
211+
)
212+
}
213+
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_with_pb_full]
142214
@Composable
143215
fun MyList(
144216
onItemClick: (MyItem) -> Unit,

0 commit comments

Comments
 (0)