1717package com.example.compose.snippets.adaptivelayouts
1818
1919import android.os.Parcelable
20- import androidx.activity.compose.BackHandler
2120import androidx.compose.foundation.background
2221import androidx.compose.foundation.clickable
2322import androidx.compose.foundation.layout.Column
@@ -30,33 +29,38 @@ import androidx.compose.material3.Card
3029import androidx.compose.material3.ListItem
3130import androidx.compose.material3.Text
3231import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
32+ import androidx.compose.material3.adaptive.WindowAdaptiveInfo
33+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
3334import androidx.compose.material3.adaptive.layout.AnimatedPane
3435import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
3536import 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
3641import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
3742import androidx.compose.runtime.Composable
43+ import androidx.compose.runtime.rememberCoroutineScope
3844import androidx.compose.ui.Modifier
3945import androidx.compose.ui.graphics.Color
4046import androidx.compose.ui.tooling.preview.Preview
4147import androidx.compose.ui.unit.dp
4248import androidx.compose.ui.unit.sp
49+ import androidx.window.core.layout.WindowWidthSizeClass
50+ import kotlinx.coroutines.launch
4351import kotlinx.parcelize.Parcelize
4452
4553@OptIn(ExperimentalMaterial3AdaptiveApi ::class )
4654@Composable
47- fun SampleListDetailPaneScaffoldParts () {
55+ fun SampleNavigableListDetailPaneScaffoldParts () {
4856 // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part02]
49- val navigator = rememberListDetailPaneScaffoldNavigator<MyItem >()
50-
51- BackHandler (navigator.canNavigateBack()) {
52- navigator.navigateBack()
53- }
57+ val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem >()
58+ val scope = rememberCoroutineScope()
5459 // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part02]
5560
5661 // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part03]
57- ListDetailPaneScaffold (
58- directive = navigator.scaffoldDirective,
59- value = navigator.scaffoldValue,
62+ NavigableListDetailPaneScaffold (
63+ navigator = scaffoldNavigator,
6064 // [START_EXCLUDE]
6165 listPane = {},
6266 detailPane = {},
@@ -65,16 +69,21 @@ fun SampleListDetailPaneScaffoldParts() {
6569 // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part03]
6670
6771 // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part04]
68- ListDetailPaneScaffold (
69- directive = navigator.scaffoldDirective,
70- value = navigator.scaffoldValue,
72+ NavigableListDetailPaneScaffold (
73+ navigator = scaffoldNavigator,
7174 listPane = {
7275 AnimatedPane {
7376 MyList (
7477 onItemClick = { item ->
7578 // Navigate to the detail pane with the passed item
76- navigator.navigateTo(ListDetailPaneScaffoldRole .Detail , item)
77- }
79+ scope.launch {
80+ scaffoldNavigator
81+ .navigateTo(
82+ ListDetailPaneScaffoldRole .Detail ,
83+ item
84+ )
85+ }
86+ },
7887 )
7988 }
8089 },
@@ -85,16 +94,14 @@ fun SampleListDetailPaneScaffoldParts() {
8594 // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part04]
8695
8796 // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part05]
88- ListDetailPaneScaffold (
89- directive = navigator.scaffoldDirective,
90- value = navigator.scaffoldValue,
91- listPane =
97+ NavigableListDetailPaneScaffold (
98+ navigator = scaffoldNavigator,
9299 // [START_EXCLUDE]
93- {},
100+ listPane = {},
94101 // [END_EXCLUDE]
95102 detailPane = {
96103 AnimatedPane {
97- navigator .currentDestination?.content ?.let {
104+ scaffoldNavigator .currentDestination?.contentKey ?.let {
98105 MyDetails (it)
99106 }
100107 }
@@ -106,39 +113,100 @@ fun SampleListDetailPaneScaffoldParts() {
106113@OptIn(ExperimentalMaterial3AdaptiveApi ::class )
107114@Preview
108115@Composable
109- fun SampleListDetailPaneScaffoldFull () {
110- // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
111- val navigator = rememberListDetailPaneScaffoldNavigator<MyItem >()
116+ fun SampleNavigableListDetailPaneScaffoldFull () {
117+ // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
118+ val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem >()
119+ val scope = rememberCoroutineScope()
112120
113- BackHandler (navigator.canNavigateBack()) {
114- navigator.navigateBack()
115- }
121+ NavigableListDetailPaneScaffold (
122+ navigator = scaffoldNavigator,
123+ listPane = {
124+ AnimatedPane {
125+ MyList (
126+ onItemClick = { item ->
127+ // Navigate to the detail pane with the passed item
128+ scope.launch {
129+ scaffoldNavigator.navigateTo(
130+ ListDetailPaneScaffoldRole .Detail ,
131+ item
132+ )
133+ }
134+ },
135+ )
136+ }
137+ },
138+ detailPane = {
139+ AnimatedPane {
140+ // Show the detail pane content if selected item is available
141+ scaffoldNavigator.currentDestination?.contentKey?.let {
142+ MyDetails (it)
143+ }
144+ }
145+ },
146+ )
147+ // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
148+ }
149+
150+ @OptIn(ExperimentalMaterial3AdaptiveApi ::class )
151+ @Composable
152+ fun SampleListDetailPaneScaffoldWithPredictiveBackFull () {
153+ // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_with_pb_full]
154+ val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem >()
155+ val customScaffoldDirective = customPaneScaffoldDirective(currentWindowAdaptiveInfo())
156+ val scope = rememberCoroutineScope()
157+
158+ ThreePaneScaffoldPredictiveBackHandler (
159+ navigator = scaffoldNavigator,
160+ backBehavior = BackNavigationBehavior .PopUntilContentChange
161+ )
116162
117163 ListDetailPaneScaffold (
118- directive = navigator.scaffoldDirective ,
119- value = navigator.scaffoldValue ,
164+ directive = customScaffoldDirective ,
165+ scaffoldState = scaffoldNavigator.scaffoldState ,
120166 listPane = {
121167 AnimatedPane {
122168 MyList (
123169 onItemClick = { item ->
124170 // Navigate to the detail pane with the passed item
125- navigator.navigateTo(ListDetailPaneScaffoldRole .Detail , item)
171+ scope.launch {
172+ scaffoldNavigator.navigateTo(
173+ ListDetailPaneScaffoldRole .Detail ,
174+ item
175+ )
176+ }
126177 },
127178 )
128179 }
129180 },
130181 detailPane = {
131182 AnimatedPane {
132183 // Show the detail pane content if selected item is available
133- navigator .currentDestination?.content ?.let {
184+ scaffoldNavigator .currentDestination?.contentKey ?.let {
134185 MyDetails (it)
135186 }
136187 }
137188 },
138189 )
139- // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
140190}
141191
192+ fun customPaneScaffoldDirective (currentWindowAdaptiveInfo : WindowAdaptiveInfo ): PaneScaffoldDirective {
193+ val horizontalPartitions =
194+ when (currentWindowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) {
195+ WindowWidthSizeClass .COMPACT -> 1
196+ WindowWidthSizeClass .MEDIUM -> 2
197+ else -> 3
198+ }
199+
200+ return PaneScaffoldDirective (
201+ maxHorizontalPartitions = horizontalPartitions,
202+ horizontalPartitionSpacerSize = 16 .dp,
203+ maxVerticalPartitions = 1 ,
204+ verticalPartitionSpacerSize = 8 .dp,
205+ defaultPanePreferredWidth = 320 .dp,
206+ excludedBounds = emptyList()
207+ )
208+ }
209+ // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_with_pb_full]
142210@Composable
143211fun MyList (
144212 onItemClick : (MyItem ) -> Unit ,
0 commit comments