Allow new routes to be pushed onto the back stack

dt/nav3-c
Don Turner 2 months ago
parent 16d8d46405
commit ba07375de1

@ -53,7 +53,7 @@ fun NiaNavHost(
val navController = appState.navController val navController = appState.navController
NavDisplay( NavDisplay(
backStack = appState.nav3Navigator.backStack, backStack = appState.nav3Navigator.backStack,
onBack = { }, onBack = { appState.nav3Navigator.goBack() },
entryProvider = entryProvider( entryProvider = entryProvider(
fallback = { key -> fallback = { key ->
println("$key not found, using fallback entry") println("$key not found, using fallback entry")
@ -73,7 +73,7 @@ fun NiaNavHost(
) )
} }
composable<BookmarksRoute> { composable<BookmarksRoute> {
Text("Legacy route") Text("Legacy BookmarksRoute")
} }
searchScreen( searchScreen(
onBackClick = navController::popBackStack, onBackClick = navController::popBackStack,

@ -16,17 +16,13 @@
package com.google.samples.apps.nowinandroid.ui package com.google.samples.apps.nowinandroid.ui
import android.os.Bundle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute import androidx.navigation.NavDestination.Companion.hasRoute
@ -34,8 +30,8 @@ import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.NavOptions import androidx.navigation.NavOptions
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import androidx.navigation.internalToRoute
import androidx.navigation.navOptions import androidx.navigation.navOptions
import androidx.navigation.toRoute
import androidx.tracing.trace import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
@ -43,7 +39,6 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.BookmarksRoute import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.BookmarksRoute
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.navigateToBookmarks import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.navigateToBookmarks
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests
import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch
@ -218,6 +213,10 @@ private fun NavigationTrackingSideEffect(navController: NavHostController) {
class Nav3NavigatorSimple(val navController: NavHostController){ class Nav3NavigatorSimple(val navController: NavHostController){
private val migratedRoutes = listOf(
BookmarksRoute::class
).associateBy { it.qualifiedName }
// TODO: We are using Dispatchers.Main so that we can access SavedStateHandle in toRoute, // TODO: We are using Dispatchers.Main so that we can access SavedStateHandle in toRoute,
// however, this may be unnecessary if we can just deserialize the route from memory // however, this may be unnecessary if we can just deserialize the route from memory
val coroutineScope = CoroutineScope(Job() + Dispatchers.Main) val coroutineScope = CoroutineScope(Job() + Dispatchers.Main)
@ -229,45 +228,44 @@ class Nav3NavigatorSimple(val navController: NavHostController){
coroutineScope.launch { coroutineScope.launch {
navController.currentBackStack.collect { nav2BackStack -> navController.currentBackStack.collect { nav2BackStack ->
with(backStack) { with(backStack) {
nav2BackStack.forEach { nav2Entry ->
nav2Entry.savedStateHandle.toRoute()
}
println("Nav2 backstack changed, size: ${backStack.size}") println("Nav2 backstack changed, size: ${backStack.size}")
if (backStack.isNotEmpty()){ if (backStack.isNotEmpty()){
clear() clear()
val entriesToAdd = nav2BackStack.mapNotNull { entry ->
for (nav2Entry in nav2BackStack){ println("Evaluating: ${entry.destination::class.qualifiedName}")
val routeClass = nav2Entry.toNav3Route() // Ignore nav graph root entries
if (routeClass != null){ if (entry.destination::class.qualifiedName == "androidx.navigation.compose.ComposeNavGraphNavigator.ComposeNavGraph"){
add(routeClass) null
} else {
val migratedRouteClass = migratedRoutes[entry.destination.route]
if (migratedRouteClass != null){
entry.savedStateHandle.internalToRoute(route = migratedRouteClass, typeMap = emptyMap())
} else { } else {
add(nav2Entry) entry
} }
} }
println("Nav3 backstack updated")
} }
addAll(entriesToAdd)
println("Nav3 backstack updated: $backStack")
} }
} }
} }
} }
fun goTo(route: Any, navOptions: NavOptions? = null){
navController.navigate(route, navOptions)
} }
fun goBack(){ fun goBack(){
backStack.removeLastOrNull()
navController.popBackStack() navController.popBackStack()
} }
}
private fun NavBackStackEntry.toNav3Route() : Any? { fun goTo(route: Any, navOptions: NavOptions? = null){
return when(this.destination.route){ backStack.add(route)
BookmarksRoute::class.qualifiedName -> { this.savedStateHandle.toRoute<BookmarksRoute>() } navController.navigate(route = route, navOptions = navOptions)
else -> null
} }
} }
/* /*
class Nav3Navigator<T: Any>(val navController: NavHostController, startRoute: T) { class Nav3Navigator<T: Any>(val navController: NavHostController, startRoute: T) {
@ -379,3 +377,5 @@ class Nav3Navigator<T: Any>(val navController: NavHostController, startRoute: T)
}*/ }*/

Loading…
Cancel
Save