Skip to content

Commit f3cf237

Browse files
committed
Update to material3-adaptive 1.1
Change-Id: I4b3b68face17149ab87135df28baa41cd5bacb0f
1 parent e308246 commit f3cf237

File tree

5 files changed

+110
-25
lines changed

5 files changed

+110
-25
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ dependencies {
8686
implementation(projects.sync.work)
8787

8888
implementation(libs.androidx.activity.compose)
89+
implementation(libs.androidx.compose.material3)
8990
implementation(libs.androidx.compose.material3.adaptive)
9091
implementation(libs.androidx.compose.material3.adaptive.layout)
9192
implementation(libs.androidx.compose.material3.adaptive.navigation)

app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,36 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane
1818

1919
import androidx.activity.compose.BackHandler
2020
import androidx.annotation.Keep
21+
import androidx.compose.foundation.interaction.MutableInteractionSource
22+
import androidx.compose.foundation.layout.Box
23+
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
24+
import androidx.compose.material3.VerticalDragHandle
2125
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
2226
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
2327
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
2428
import androidx.compose.material3.adaptive.layout.AnimatedPane
2529
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
2630
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
2731
import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
32+
import androidx.compose.material3.adaptive.layout.PaneExpansionAnchor
2833
import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
2934
import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective
35+
import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
3036
import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
3137
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
3238
import androidx.compose.runtime.Composable
3339
import androidx.compose.runtime.getValue
3440
import androidx.compose.runtime.key
3541
import androidx.compose.runtime.mutableStateOf
3642
import androidx.compose.runtime.remember
43+
import androidx.compose.runtime.rememberCoroutineScope
3744
import androidx.compose.runtime.saveable.Saver
3845
import androidx.compose.runtime.saveable.rememberSaveable
3946
import androidx.compose.runtime.setValue
47+
import androidx.compose.ui.Modifier
48+
import androidx.compose.ui.draw.clipToBounds
49+
import androidx.compose.ui.layout.layout
50+
import androidx.compose.ui.unit.dp
4051
import androidx.hilt.navigation.compose.hiltViewModel
4152
import androidx.lifecycle.compose.collectAsStateWithLifecycle
4253
import androidx.navigation.NavGraphBuilder
@@ -49,8 +60,10 @@ import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder
4960
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute
5061
import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic
5162
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
63+
import kotlinx.coroutines.launch
5264
import kotlinx.serialization.Serializable
5365
import java.util.UUID
66+
import kotlin.math.max
5467

5568
@Serializable internal object TopicPlaceholderRoute
5669

@@ -93,8 +106,20 @@ internal fun InterestsListDetailScreen(
93106
},
94107
),
95108
)
109+
val coroutineScope = rememberCoroutineScope()
110+
111+
val paneExpansionState = rememberPaneExpansionState(
112+
anchors = listOf(
113+
PaneExpansionAnchor.Proportion(0f),
114+
PaneExpansionAnchor.Proportion(0.5f),
115+
PaneExpansionAnchor.Proportion(1f),
116+
),
117+
)
118+
96119
BackHandler(listDetailNavigator.canNavigateBack()) {
97-
listDetailNavigator.navigateBack()
120+
coroutineScope.launch {
121+
listDetailNavigator.navigateBack()
122+
}
98123
}
99124

100125
var nestedNavHostStartRoute by remember {
@@ -123,40 +148,99 @@ internal fun InterestsListDetailScreen(
123148
nestedNavHostStartRoute = TopicRoute(id = topicId)
124149
nestedNavKey = UUID.randomUUID()
125150
}
126-
listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
151+
coroutineScope.launch {
152+
listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
153+
}
127154
}
128155

156+
val mutableInteractionSource = remember { MutableInteractionSource() }
157+
val minPaneWidth = 300.dp
158+
129159
ListDetailPaneScaffold(
130160
value = listDetailNavigator.scaffoldValue,
131161
directive = listDetailNavigator.scaffoldDirective,
132162
listPane = {
133163
AnimatedPane {
134-
InterestsRoute(
135-
onTopicClick = ::onTopicClickShowDetailPane,
136-
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
137-
)
164+
Box(
165+
modifier = Modifier.clipToBounds()
166+
.layout { measurable, constraints ->
167+
val width = max(minPaneWidth.roundToPx(), constraints.maxWidth)
168+
val placeable = measurable.measure(
169+
constraints.copy(
170+
minWidth = minPaneWidth.roundToPx(),
171+
maxWidth = width,
172+
),
173+
)
174+
layout(constraints.maxWidth, placeable.height) {
175+
placeable.placeRelative(
176+
x = 0,
177+
y = 0,
178+
)
179+
}
180+
},
181+
) {
182+
InterestsRoute(
183+
onTopicClick = ::onTopicClickShowDetailPane,
184+
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
185+
)
186+
}
138187
}
139188
},
140189
detailPane = {
141190
AnimatedPane {
142-
key(nestedNavKey) {
143-
NavHost(
144-
navController = nestedNavController,
145-
startDestination = nestedNavHostStartRoute,
146-
route = DetailPaneNavHostRoute::class,
147-
) {
148-
topicScreen(
149-
showBackButton = !listDetailNavigator.isListPaneVisible(),
150-
onBackClick = listDetailNavigator::navigateBack,
151-
onTopicClick = ::onTopicClickShowDetailPane,
152-
)
153-
composable<TopicPlaceholderRoute> {
154-
TopicDetailPlaceholder()
191+
Box(
192+
modifier = Modifier.clipToBounds()
193+
.layout { measurable, constraints ->
194+
val width = max(minPaneWidth.roundToPx(), constraints.maxWidth)
195+
val placeable = measurable.measure(
196+
constraints.copy(
197+
minWidth = minPaneWidth.roundToPx(),
198+
maxWidth = width,
199+
),
200+
)
201+
layout(constraints.maxWidth, placeable.height) {
202+
placeable.placeRelative(
203+
x = constraints.maxWidth -
204+
max(constraints.maxWidth, placeable.width),
205+
y = 0,
206+
)
207+
}
208+
},
209+
) {
210+
key(nestedNavKey) {
211+
NavHost(
212+
navController = nestedNavController,
213+
startDestination = nestedNavHostStartRoute,
214+
route = DetailPaneNavHostRoute::class,
215+
) {
216+
topicScreen(
217+
showBackButton = !listDetailNavigator.isListPaneVisible(),
218+
onBackClick = {
219+
coroutineScope.launch {
220+
listDetailNavigator.navigateBack()
221+
}
222+
},
223+
onTopicClick = ::onTopicClickShowDetailPane,
224+
)
225+
composable<TopicPlaceholderRoute> {
226+
TopicDetailPlaceholder()
227+
}
155228
}
156229
}
157230
}
158231
}
159232
},
233+
paneExpansionState = paneExpansionState,
234+
paneExpansionDragHandle = {
235+
VerticalDragHandle(
236+
modifier = Modifier.paneExpansionDraggable(
237+
state = paneExpansionState,
238+
minTouchTargetSize = LocalMinimumInteractiveComponentSize.current,
239+
interactionSource = mutableInteractionSource,
240+
),
241+
interactionSource = mutableInteractionSource,
242+
)
243+
},
160244
)
161245
}
162246

feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ internal fun InterestsScreen(
7070
when (uiState) {
7171
InterestsUiState.Loading ->
7272
NiaLoadingWheel(
73-
modifier = modifier,
7473
contentDesc = stringResource(id = R.string.feature_interests_loading),
7574
)
7675

@@ -81,7 +80,6 @@ internal fun InterestsScreen(
8180
onFollowButtonClick = followTopic,
8281
selectedTopicId = uiState.selectedTopicId,
8382
highlightSelectedTopic = highlightSelectedTopic,
84-
modifier = modifier,
8583
)
8684

8785
is InterestsUiState.Empty -> InterestsEmptyScreen()

feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ fun TopicsTabContent(
7575
onClick = { onTopicClick(topicId) },
7676
onFollowButtonClick = { onFollowButtonClick(topicId, it) },
7777
isSelected = isSelected,
78+
modifier = Modifier.fillMaxWidth(),
7879
)
7980
}
8081
}

gradle/libs.versions.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ androidxAppCompat = "1.7.0"
99
androidxBrowser = "1.8.0"
1010
androidxComposeBom = "2024.12.01"
1111
androidxComposeFoundation = "1.8.0-alpha07"
12+
androidxComposeMaterial3Adaptive = "1.1.0-alpha08"
1213
androidxComposeRuntimeTracing = "1.7.6"
1314
androidxCore = "1.15.0"
1415
androidxCoreSplashscreen = "1.0.1"
@@ -69,15 +70,15 @@ androidx-activity-compose = { group = "androidx.activity", name = "activity-comp
6970
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" }
7071
androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidxMacroBenchmark" }
7172
androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidxBrowser" }
72-
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
73+
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom-alpha", version.ref = "androidxComposeBom" }
7374
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "androidxComposeFoundation" }
7475
androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" }
7576
androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" }
7677
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
7778
androidx-compose-material3-navigationSuite = { group = "androidx.compose.material3", name = "material3-adaptive-navigation-suite" }
78-
androidx-compose-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive" }
79-
androidx-compose-material3-adaptive-layout = { group = "androidx.compose.material3.adaptive", name = "adaptive-layout" }
80-
androidx-compose-material3-adaptive-navigation = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation" }
79+
androidx-compose-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive", version.ref = "androidxComposeMaterial3Adaptive" }
80+
androidx-compose-material3-adaptive-layout = { group = "androidx.compose.material3.adaptive", name = "adaptive-layout", version.ref = "androidxComposeMaterial3Adaptive" }
81+
androidx-compose-material3-adaptive-navigation = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation", version.ref = "androidxComposeMaterial3Adaptive" }
8182
androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" }
8283
androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
8384
androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidxComposeRuntimeTracing" }

0 commit comments

Comments
 (0)