@@ -18,14 +18,21 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane
1818
1919import androidx.activity.compose.BackHandler
2020import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
21+ import androidx.compose.material3.adaptive.layout.AnimatedPane
2122import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
2223import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
2324import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
25+ import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
2426import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
2527import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
2628import androidx.compose.runtime.Composable
27- import androidx.compose.runtime.LaunchedEffect
2829import androidx.compose.runtime.getValue
30+ import androidx.compose.runtime.key
31+ import androidx.compose.runtime.mutableStateOf
32+ import androidx.compose.runtime.remember
33+ import androidx.compose.runtime.saveable.Saver
34+ import androidx.compose.runtime.saveable.rememberSaveable
35+ import androidx.compose.runtime.setValue
2936import androidx.hilt.navigation.compose.hiltViewModel
3037import androidx.lifecycle.compose.collectAsStateWithLifecycle
3138import androidx.navigation.NavGraphBuilder
@@ -39,8 +46,10 @@ import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERES
3946import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG
4047import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder
4148import com.google.samples.apps.nowinandroid.feature.topic.navigation.TOPIC_ROUTE
49+ import com.google.samples.apps.nowinandroid.feature.topic.navigation.createTopicRoute
4250import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic
4351import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
52+ import java.util.UUID
4453
4554private const val DETAIL_PANE_NAVHOST_ROUTE = " detail_pane_route"
4655
@@ -76,17 +85,42 @@ internal fun InterestsListDetailScreen(
7685 selectedTopicId : String? ,
7786 onTopicClick : (String ) -> Unit ,
7887) {
79- val listDetailNavigator = rememberListDetailPaneScaffoldNavigator()
88+ val listDetailNavigator = rememberListDetailPaneScaffoldNavigator(
89+ initialDestinationHistory = listOfNotNull(
90+ ThreePaneScaffoldDestinationItem (ListDetailPaneScaffoldRole .List ),
91+ ThreePaneScaffoldDestinationItem <Nothing >(ListDetailPaneScaffoldRole .Detail ).takeIf {
92+ selectedTopicId != null
93+ },
94+ ),
95+ )
8096 BackHandler (listDetailNavigator.canNavigateBack()) {
8197 listDetailNavigator.navigateBack()
8298 }
8399
84- val nestedNavController = rememberNavController()
100+ var nestedNavHostStartDestination by remember {
101+ mutableStateOf(selectedTopicId?.let (::createTopicRoute) ? : TOPIC_ROUTE )
102+ }
103+ var nestedNavKey by rememberSaveable(
104+ stateSaver = Saver ({ it.toString() }, UUID ::fromString),
105+ ) {
106+ mutableStateOf(UUID .randomUUID())
107+ }
108+ val nestedNavController = key(nestedNavKey) {
109+ rememberNavController()
110+ }
85111
86112 fun onTopicClickShowDetailPane (topicId : String ) {
87113 onTopicClick(topicId)
88- nestedNavController.navigateToTopic(topicId) {
89- popUpTo(DETAIL_PANE_NAVHOST_ROUTE )
114+ if (listDetailNavigator.isDetailPaneVisible()) {
115+ // If the detail pane was visible, then use the nestedNavController navigate call
116+ // directly
117+ nestedNavController.navigateToTopic(topicId) {
118+ popUpTo(DETAIL_PANE_NAVHOST_ROUTE )
119+ }
120+ } else {
121+ // Otherwise, recreate the NavHost entirely, and start at the new destination
122+ nestedNavHostStartDestination = createTopicRoute(topicId)
123+ nestedNavKey = UUID .randomUUID()
90124 }
91125 listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole .Detail )
92126 }
@@ -95,34 +129,34 @@ internal fun InterestsListDetailScreen(
95129 value = listDetailNavigator.scaffoldValue,
96130 directive = listDetailNavigator.scaffoldDirective,
97131 listPane = {
98- InterestsRoute (
99- onTopicClick = ::onTopicClickShowDetailPane,
100- highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
101- )
102- },
103- detailPane = {
104- NavHost (
105- navController = nestedNavController,
106- startDestination = TOPIC_ROUTE ,
107- route = DETAIL_PANE_NAVHOST_ROUTE ,
108- ) {
109- topicScreen(
110- showBackButton = ! listDetailNavigator.isListPaneVisible(),
111- onBackClick = listDetailNavigator::navigateBack,
132+ AnimatedPane {
133+ InterestsRoute (
112134 onTopicClick = ::onTopicClickShowDetailPane,
135+ highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
113136 )
114- composable(route = TOPIC_ROUTE ) {
115- TopicDetailPlaceholder ()
137+ }
138+ },
139+ detailPane = {
140+ AnimatedPane {
141+ key(nestedNavKey) {
142+ NavHost (
143+ navController = nestedNavController,
144+ startDestination = nestedNavHostStartDestination,
145+ route = DETAIL_PANE_NAVHOST_ROUTE ,
146+ ) {
147+ topicScreen(
148+ showBackButton = ! listDetailNavigator.isListPaneVisible(),
149+ onBackClick = listDetailNavigator::navigateBack,
150+ onTopicClick = ::onTopicClickShowDetailPane,
151+ )
152+ composable(route = TOPIC_ROUTE ) {
153+ TopicDetailPlaceholder ()
154+ }
155+ }
116156 }
117157 }
118158 },
119159 )
120- LaunchedEffect (Unit ) {
121- if (selectedTopicId != null ) {
122- // Initial topic ID was provided when navigating to Interests, so show its details.
123- onTopicClickShowDetailPane(selectedTopicId)
124- }
125- }
126160}
127161
128162@OptIn(ExperimentalMaterial3AdaptiveApi ::class )
0 commit comments