Skip to content

Commit 9b0c8e1

Browse files
committed
[AdaptiveUiCodelab] Use ListDetailPaneScaffold
1 parent 21359ec commit 9b0c8e1

File tree

4 files changed

+54
-73
lines changed

4 files changed

+54
-73
lines changed

AdaptiveUiCodelab/app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ dependencies {
7373

7474
implementation(libs.androidx.material3)
7575
implementation(libs.androidx.material3.adaptive)
76+
implementation(libs.androidx.material3.adaptive.layout)
7677
implementation(libs.androidx.material3.adaptive.nav.suite)
78+
implementation(libs.androidx.material3.adaptive.navigation)
7779
implementation(libs.androidx.material.icons.extended)
7880
implementation(libs.androidx.ui.tooling.preview)
7981
androidTestImplementation(libs.androidx.ui.test.junit4)

AdaptiveUiCodelab/app/src/main/java/com/example/reply/ui/ReplyApp.kt

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,62 +16,37 @@
1616

1717
package com.example.reply.ui
1818

19-
import androidx.compose.foundation.layout.fillMaxSize
2019
import androidx.compose.material3.Icon
2120
import androidx.compose.material3.Text
21+
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
22+
import androidx.compose.material3.adaptive.layout.AnimatedPane
23+
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
24+
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
2225
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
2326
import androidx.compose.runtime.Composable
2427
import androidx.compose.runtime.getValue
2528
import androidx.compose.runtime.mutableStateOf
2629
import androidx.compose.runtime.remember
2730
import androidx.compose.runtime.setValue
28-
import androidx.compose.ui.Modifier
2931
import androidx.compose.ui.res.stringResource
3032
import androidx.window.core.layout.WindowWidthSizeClass
33+
import com.example.reply.data.Email
3134
import com.example.reply.ui.utils.DevicePosture
32-
import com.example.reply.ui.utils.ReplyContentType
3335

3436
@Composable
3537
fun ReplyApp(
3638
windowSize: WindowWidthSizeClass,
3739
foldingDevicePosture: DevicePosture,
3840
replyHomeUIState: ReplyHomeUIState
3941
) {
40-
/**
41-
* This will help us select type of navigation and content type depending on window size and
42-
* fold state of the device.
43-
*
44-
* In the state of folding device If it's half fold in BookPosture we want to avoid content
45-
* at the crease/hinge
46-
*/
47-
val contentType: ReplyContentType
48-
49-
when (windowSize) {
50-
WindowWidthSizeClass.COMPACT -> {
51-
contentType = ReplyContentType.LIST_ONLY
52-
}
53-
WindowWidthSizeClass.MEDIUM -> {
54-
contentType = if (foldingDevicePosture != DevicePosture.NormalPosture) {
55-
ReplyContentType.LIST_AND_DETAIL
56-
} else {
57-
ReplyContentType.LIST_ONLY
58-
}
59-
}
60-
WindowWidthSizeClass.EXPANDED -> {
61-
contentType = ReplyContentType.LIST_AND_DETAIL
62-
}
63-
else -> {
64-
contentType = ReplyContentType.LIST_ONLY
65-
}
42+
ReplyNavigationWrapperUI {
43+
ReplyAppContent(replyHomeUIState)
6644
}
67-
68-
ReplyNavigationWrapperUI(contentType, replyHomeUIState)
6945
}
7046

7147
@Composable
7248
private fun ReplyNavigationWrapperUI(
73-
contentType: ReplyContentType,
74-
replyHomeUIState: ReplyHomeUIState
49+
content: @Composable () -> Unit = {}
7550
) {
7651
var selectedDestination: ReplyDestination by remember {
7752
mutableStateOf(ReplyDestination.Inbox)
@@ -88,25 +63,33 @@ private fun ReplyNavigationWrapperUI(
8863
}
8964
}
9065
) {
91-
ReplyAppContent(contentType, replyHomeUIState)
66+
content()
9267
}
9368
}
9469

9570

71+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
9672
@Composable
9773
fun ReplyAppContent(
98-
contentType: ReplyContentType,
9974
replyHomeUIState: ReplyHomeUIState,
10075
) {
101-
if (contentType == ReplyContentType.LIST_AND_DETAIL) {
102-
ReplyListAndDetailContent(
103-
replyHomeUIState = replyHomeUIState,
104-
modifier = Modifier.fillMaxSize(),
105-
)
106-
} else {
107-
ReplyListOnlyContent(
108-
replyHomeUIState = replyHomeUIState,
109-
modifier = Modifier.fillMaxSize(),
110-
)
111-
}
76+
val selectedEmail: Email? = replyHomeUIState.emails.firstOrNull()
77+
val navigator = rememberListDetailPaneScaffoldNavigator()
78+
79+
ListDetailPaneScaffold(
80+
directive = navigator.scaffoldDirective,
81+
value = navigator.scaffoldValue,
82+
listPane = {
83+
AnimatedPane {
84+
ReplyListPane(replyHomeUIState)
85+
}
86+
},
87+
detailPane = {
88+
AnimatedPane {
89+
if (selectedEmail != null) {
90+
ReplyDetailPane(selectedEmail)
91+
}
92+
}
93+
}
94+
)
11295
}

AdaptiveUiCodelab/app/src/main/java/com/example/reply/ui/ReplyListContent.kt

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import com.example.reply.R
5151
import com.example.reply.data.Email
5252

5353
@Composable
54-
fun ReplyListOnlyContent(
54+
fun ReplyListPane(
5555
replyHomeUIState: ReplyHomeUIState,
5656
modifier: Modifier = Modifier
5757
) {
@@ -66,24 +66,13 @@ fun ReplyListOnlyContent(
6666
}
6767

6868
@Composable
69-
fun ReplyListAndDetailContent(
70-
replyHomeUIState: ReplyHomeUIState,
71-
modifier: Modifier = Modifier,
72-
selectedItemIndex: Int = 0
69+
fun ReplyDetailPane(
70+
email: Email,
71+
modifier: Modifier = Modifier
7372
) {
74-
Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(12.dp)) {
75-
LazyColumn(modifier = modifier.weight(1f)) {
76-
item {
77-
ReplySearchBar(modifier = Modifier.fillMaxWidth())
78-
}
79-
items(replyHomeUIState.emails) { email ->
80-
ReplyEmailListItem(email = email)
81-
}
82-
}
83-
LazyColumn(modifier = modifier.weight(1f)) {
84-
items(replyHomeUIState.emails[selectedItemIndex].threads) { email ->
85-
ReplyEmailThreadItem(email = email)
86-
}
73+
LazyColumn(modifier = modifier) {
74+
items(email.threads) {
75+
ReplyEmailThreadItem(it)
8776
}
8877
}
8978
}
@@ -92,15 +81,16 @@ fun ReplyListAndDetailContent(
9281
@Composable
9382
fun ReplyEmailListItem(
9483
email: Email,
95-
modifier: Modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)) {
84+
modifier: Modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
85+
) {
9686
Card(modifier = modifier) {
9787
Column(
9888
modifier = Modifier
9989
.fillMaxWidth()
10090
.padding(20.dp)
10191
) {
10292
Row(modifier = Modifier.fillMaxWidth()) {
103-
ReplyProfileImage(
93+
ReplyProfileImage(
10494
drawableResource = email.sender.avatar,
10595
description = email.sender.fullName,
10696
)
@@ -155,15 +145,19 @@ fun ReplyEmailListItem(
155145
@Composable
156146
fun ReplyEmailThreadItem(
157147
email: Email,
158-
modifier: Modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)) {
159-
Card(modifier = modifier, colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)) {
148+
modifier: Modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
149+
) {
150+
Card(
151+
modifier = modifier,
152+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
153+
) {
160154
Column(
161155
modifier = Modifier
162156
.fillMaxWidth()
163157
.padding(20.dp)
164158
) {
165159
Row(modifier = Modifier.fillMaxWidth()) {
166-
ReplyProfileImage(
160+
ReplyProfileImage(
167161
drawableResource = email.sender.avatar,
168162
description = email.sender.fullName,
169163
)
@@ -203,13 +197,13 @@ fun ReplyEmailThreadItem(
203197
color = MaterialTheme.colorScheme.outline,
204198
modifier = Modifier.padding(top = 12.dp, bottom = 8.dp),
205199
)
206-
200+
207201
Text(
208202
text = email.body,
209203
style = MaterialTheme.typography.bodyLarge,
210204
color = MaterialTheme.colorScheme.onSurfaceVariant,
211205
)
212-
206+
213207
Row(
214208
modifier = Modifier
215209
.fillMaxWidth()
@@ -284,4 +278,4 @@ fun ReplySearchBar(modifier: Modifier = Modifier) {
284278
.size(32.dp)
285279
)
286280
}
287-
}
281+
}

AdaptiveUiCodelab/gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ kotlin = "1.9.23"
1010
kotlinxCoroutinesAndroid = "1.8.0"
1111
lifecycleViewmodelCompose = "2.7.0"
1212
lifecycleRuntimeKtx = "2.7.0"
13-
material3Adaptive = "1.0.0-alpha12"
13+
material3Adaptive = "1.0.0-beta01"
1414
material3AdaptiveNavSuite = "1.3.0-beta01"
1515
window = "1.2.0"
1616

@@ -25,7 +25,9 @@ androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-
2525
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
2626
androidx-material3 = { module = "androidx.compose.material3:material3" }
2727
androidx-material3-adaptive = { module = "androidx.compose.material3.adaptive:adaptive", version.ref = "material3Adaptive" }
28+
androidx-material3-adaptive-layout = { module = "androidx.compose.material3.adaptive:adaptive-layout", version.ref = "material3Adaptive" }
2829
androidx-material3-adaptive-nav-suite = { module = "androidx.compose.material3:material3-adaptive-navigation-suite", version.ref = "material3AdaptiveNavSuite" }
30+
androidx-material3-adaptive-navigation = { module = "androidx.compose.material3.adaptive:adaptive-navigation", version.ref = "material3Adaptive" }
2931
androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
3032
androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
3133
androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" }

0 commit comments

Comments
 (0)