17
17
package com.example.compose.snippets.adaptivelayouts
18
18
19
19
import android.os.Parcelable
20
- import androidx.activity.compose.BackHandler
21
20
import androidx.compose.foundation.background
22
21
import androidx.compose.foundation.clickable
23
22
import androidx.compose.foundation.layout.Column
@@ -30,33 +29,39 @@ import androidx.compose.material3.Card
30
29
import androidx.compose.material3.ListItem
31
30
import androidx.compose.material3.Text
32
31
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
32
+ import androidx.compose.material3.adaptive.WindowAdaptiveInfo
33
+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
33
34
import androidx.compose.material3.adaptive.layout.AnimatedPane
34
35
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
35
36
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
36
41
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
37
42
import androidx.compose.runtime.Composable
43
+ import androidx.compose.runtime.rememberCoroutineScope
38
44
import androidx.compose.ui.Modifier
39
45
import androidx.compose.ui.graphics.Color
40
46
import androidx.compose.ui.tooling.preview.Preview
41
47
import androidx.compose.ui.unit.dp
42
48
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
43
52
import kotlinx.parcelize.Parcelize
44
53
45
54
@OptIn(ExperimentalMaterial3AdaptiveApi ::class )
46
55
@Composable
47
- fun SampleListDetailPaneScaffoldParts () {
56
+ fun SampleNavigableListDetailPaneScaffoldParts () {
48
57
// [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()
54
60
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part02]
55
61
56
62
// [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,
60
65
// [START_EXCLUDE]
61
66
listPane = {},
62
67
detailPane = {},
@@ -65,16 +70,21 @@ fun SampleListDetailPaneScaffoldParts() {
65
70
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part03]
66
71
67
72
// [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,
71
75
listPane = {
72
76
AnimatedPane {
73
77
MyList (
74
78
onItemClick = { item ->
75
79
// 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
+ },
78
88
)
79
89
}
80
90
},
@@ -85,16 +95,14 @@ fun SampleListDetailPaneScaffoldParts() {
85
95
// [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_part04]
86
96
87
97
// [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,
92
100
// [START_EXCLUDE]
93
- {},
101
+ listPane = {},
94
102
// [END_EXCLUDE]
95
103
detailPane = {
96
104
AnimatedPane {
97
- navigator .currentDestination?.content ?.let {
105
+ scaffoldNavigator .currentDestination?.contentKey ?.let {
98
106
MyDetails (it)
99
107
}
100
108
}
@@ -106,39 +114,103 @@ fun SampleListDetailPaneScaffoldParts() {
106
114
@OptIn(ExperimentalMaterial3AdaptiveApi ::class )
107
115
@Preview
108
116
@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()
112
121
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
+ )
116
163
117
164
ListDetailPaneScaffold (
118
- directive = navigator.scaffoldDirective ,
119
- value = navigator.scaffoldValue ,
165
+ directive = customScaffoldDirective ,
166
+ scaffoldState = scaffoldNavigator.scaffoldState ,
120
167
listPane = {
121
168
AnimatedPane {
122
169
MyList (
123
170
onItemClick = { item ->
124
171
// 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
+ }
126
178
},
127
179
)
128
180
}
129
181
},
130
182
detailPane = {
131
183
AnimatedPane {
132
184
// Show the detail pane content if selected item is available
133
- navigator .currentDestination?.content ?.let {
185
+ scaffoldNavigator .currentDestination?.contentKey ?.let {
134
186
MyDetails (it)
135
187
}
136
188
}
137
189
},
138
190
)
139
- // [END android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full]
140
191
}
141
192
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]
142
214
@Composable
143
215
fun MyList (
144
216
onItemClick : (MyItem ) -> Unit ,
0 commit comments