diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt index c33b1611b..71a341f72 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt @@ -17,7 +17,6 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane import androidx.activity.compose.BackHandler -import androidx.annotation.Keep import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box @@ -27,23 +26,23 @@ import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi import androidx.compose.material3.adaptive.WindowAdaptiveInfo import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.material3.adaptive.layout.AnimatedPane -import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole import androidx.compose.material3.adaptive.layout.PaneAdaptedValue import androidx.compose.material3.adaptive.layout.PaneExpansionAnchor import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective +import androidx.compose.material3.adaptive.layout.defaultDragHandleSemantics import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState +import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior +import androidx.compose.material3.adaptive.navigation.NavigableListDetailPaneScaffold import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator +import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldPredictiveBackHandler import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds @@ -51,31 +50,20 @@ import androidx.compose.ui.layout.layout import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.viewmodel.viewModelFactory import androidx.navigation.NavGraphBuilder -import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder import com.google.samples.apps.nowinandroid.feature.topic.TopicScreen import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel -import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel_Factory import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute -import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic -import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen import kotlinx.coroutines.launch import kotlinx.serialization.Serializable -import java.util.UUID import kotlin.math.max @Serializable internal object TopicPlaceholderRoute -// TODO: Remove @Keep when https://issuetracker.google.com/353898971 is fixed -@Keep -@Serializable internal object DetailPaneNavHostRoute - fun NavGraphBuilder.interestsListDetailScreen() { composable { InterestsListDetailScreen() @@ -121,9 +109,17 @@ internal fun InterestsListDetailScreen( ), ) - BackHandler(listDetailNavigator.canNavigateBack()) { + ThreePaneScaffoldPredictiveBackHandler( + listDetailNavigator, + BackNavigationBehavior.PopUntilScaffoldValueChange, + ) + BackHandler( + paneExpansionState.currentAnchor == PaneExpansionAnchor.Proportion(0f) && + listDetailNavigator.isListPaneVisible() && + listDetailNavigator.isDetailPaneVisible(), + ) { coroutineScope.launch { - listDetailNavigator.navigateBack() + paneExpansionState.animateTo(PaneExpansionAnchor.Proportion(1f)) } } @@ -138,14 +134,18 @@ internal fun InterestsListDetailScreen( coroutineScope.launch { listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail) } + if (paneExpansionState.currentAnchor == PaneExpansionAnchor.Proportion(1f)) { + coroutineScope.launch { + paneExpansionState.animateTo(PaneExpansionAnchor.Proportion(0f)) + } + } } val mutableInteractionSource = remember { MutableInteractionSource() } val minPaneWidth = 300.dp - ListDetailPaneScaffold( - value = listDetailNavigator.scaffoldValue, - directive = listDetailNavigator.scaffoldDirective, + NavigableListDetailPaneScaffold( + navigator = listDetailNavigator, listPane = { AnimatedPane { Box( @@ -209,7 +209,7 @@ internal fun InterestsListDetailScreen( key = route.id, ) { factory -> factory.create(route.id) - } + }, ) } is TopicPlaceholderRoute -> { @@ -227,6 +227,7 @@ internal fun InterestsListDetailScreen( state = paneExpansionState, minTouchTargetSize = LocalMinimumInteractiveComponentSize.current, interactionSource = mutableInteractionSource, + semanticsProperties = paneExpansionState.defaultDragHandleSemantics(), ), interactionSource = mutableInteractionSource, ) diff --git a/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt index fabb82b10..69059c81d 100644 --- a/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt +++ b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt @@ -16,11 +16,14 @@ package com.google.samples.apps.nowinandroid.feature.topic.navigation +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptionsBuilder import androidx.navigation.compose.composable +import androidx.navigation.toRoute import com.google.samples.apps.nowinandroid.feature.topic.TopicScreen +import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel import kotlinx.serialization.Serializable @Serializable data class TopicRoute(val id: String) @@ -36,11 +39,17 @@ fun NavGraphBuilder.topicScreen( onBackClick: () -> Unit, onTopicClick: (String) -> Unit, ) { - composable { + composable { entry -> + val id = entry.toRoute().id TopicScreen( showBackButton = showBackButton, onBackClick = onBackClick, onTopicClick = onTopicClick, + viewModel = hiltViewModel( + key = id, + ) { factory -> + factory.create(id) + }, ) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 790b7a942..04eedd374 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,9 +7,9 @@ androidTools = "31.7.3" androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" -androidxComposeBom = "2024.12.01" +androidxComposeBom = "2025.02.00" androidxComposeFoundation = "1.8.0-alpha07" -androidxComposeMaterial3Adaptive = "1.1.0-alpha08" +androidxComposeMaterial3Adaptive = "1.1.0-rc01" androidxComposeRuntimeTracing = "1.7.6" androidxCore = "1.15.0" androidxCoreSplashscreen = "1.0.1"