Работает ли navController.setGraph() в безопасной навигации типа Jetpack Compose?
Вызов setGraph устанавливает график, но поскольку NavHost устанавливает navController.graph в любой из перегрузок он возвращается к исходному NavGraph, добавленному или созданному с помощью NavGraphBuilder с мгновенной вспышкой.
[img]https://i. sstatic.net/3GF3HZvl.gif[/img]
Изменение начального пункта назначения также не меняет startDestination графика. Я что-то упускаю здесь? Я тестировал обе перегрузки, результат тот же. Я ищу решение для NavHostController, где мы проверяем глубокие ссылки и соответствующим образом меняем порядок графиков на основе параметров глубоких ссылок или если требуется регистрация для доступа к NavGraphBuilder или NavGraph с параметром, но графиком из NavHostController.
@Composable
private fun MainContainer() {
val navController = rememberNavController()
// Changing this destination changes where graph will start
val startDestination = RouteA
// This NavGraph will be used with NavHost this navHostController will be assigned
val navGraph: NavGraph = remember(startDestination) {
navController.createGraph(
startDestination = startDestination
) {
addNavGraph(navController)
}
}
Column {
Button(
modifier = Modifier.fillMaxWidth().padding(16.dp),
onClick = {
navController.setGraph(
graph = navController.createGraph(startDestination = RouteC) {
addNavGraph(navController)
}, startDestinationArgs = null
)
// navController.graph.setStartDestination(RouteD)
println("Start destination: ${navController.graph.startDestinationRoute}")
}
) {
Text("Set graph")
}
/* NavHost(
modifier = Modifier.fillMaxSize(),
navController = navController,
graph = navGraph,
)
*/
NavHost(
modifier = Modifier.fillMaxSize(),
navController = navController,
startDestination = RouteA
) {
addNavGraph(navController)
}
}
}
NavGraphBuilder
private fun NavGraphBuilder.addNavGraph(navController: NavController) {
composable {
RouteAScreen(navController)
}
composable {
RouteBScreen(navController)
}
composable {
RouteCScreen(navController)
}
composable {
RouteDScreen(navController)
}
}
Экраны
@Composable
internal fun RouteAScreen(navController: NavController) {
RouteScreen(
modifier = Modifier.background(Color.White),
title = "RouteAScreen",
navController = navController
)
}
@Composable
internal fun RouteBScreen(navController: NavController) {
RouteScreen(
modifier = Modifier.background(Color.Cyan),
title = "RouteBScreen",
navController = navController
)
}
@Composable
internal fun RouteCScreen(navController: NavController) {
RouteScreen(
modifier = Modifier.background(Color.Yellow),
title = "RouteCScreen",
navController = navController
)
}
@Composable
internal fun RouteDScreen(navController: NavController) {
RouteScreen(
modifier = Modifier.background(Color.Green),
title = "RouteDScreen",
navController = navController
)
}
@SuppressLint("RestrictedApi")
@Composable
private fun RouteScreen(
modifier: Modifier = Modifier,
title: String,
navController: NavController,
) {
var popUpToRoute by remember { mutableStateOf(null) }
var popUpToInclusive by rememberSaveable {
mutableStateOf(false)
}
var isSingleTop by rememberSaveable {
mutableStateOf(false)
}
Column(
modifier = modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = title,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
ExposedSelectionMenu(title = "PopUpTo",
index = when (popUpToRoute) {
null -> 0
RouteA -> 1
RouteB -> 2
RouteC -> 3
else -> 4
},
options = listOf("no popUpTo", "RouteA", "RouteB", "RouteC", "RouteD"),
onSelected = {
popUpToRoute = when (it) {
0 -> null
1 -> RouteA
2 -> RouteB
3 -> RouteC
else -> RouteD
}
}
)
Row {
CheckBoxWithText(
title = "popUpToInclusive",
enabled = popUpToRoute != null,
checked = popUpToInclusive
) {
popUpToInclusive = it
}
Spacer(Modifier.width(8.dp))
CheckBoxWithText(
title = "singleTop",
checked = isSingleTop
) {
isSingleTop = it
}
}
NavigationButton(
navController = navController,
title = "RouteA",
targetRoute = RouteA,
popUpToRoute = popUpToRoute,
popUpToInclusive = popUpToInclusive,
singleTop = isSingleTop
)
NavigationButton(
navController = navController,
title = "RouteB",
targetRoute = RouteB,
popUpToRoute = popUpToRoute,
popUpToInclusive = popUpToInclusive,
singleTop = isSingleTop
)
NavigationButton(
navController = navController,
title = "RouteC",
targetRoute = RouteC,
popUpToRoute = popUpToRoute,
popUpToInclusive = popUpToInclusive,
singleTop = isSingleTop
)
NavigationButton(
navController = navController,
title = "RouteD",
targetRoute = RouteD,
popUpToRoute = popUpToRoute,
popUpToInclusive = popUpToInclusive,
singleTop = isSingleTop
)
val currentBackStack: List by navController.currentBackStack.collectAsState()
val packageName = LocalContext.current.packageName
LazyColumn(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
// Don't do looped operations in actual code, it's for demonstration
items(items = currentBackStack.reversed()) {
Row(
modifier = Modifier
.shadow(4.dp, RoundedCornerShape(8.dp))
.background(Color.White)
.fillMaxWidth()
.padding(16.dp)
) {
Text(
modifier = Modifier.alignByBaseline(),
text = it.destination.route
?.replace("$packageName.", "")
?.replace(
"BottomNavigationRoute.",
""
) ?: it.destination.displayName,
fontSize = 16.sp
)
val text = if (it.destination is NavGraph) "NavGraph" else "NavDestination"
Spacer(Modifier.width(4.dp))
Text(
modifier = Modifier.alignByBaseline(),
text = "($text)",
fontSize = 10.sp
)
}
}
}
}
}
@Composable
private fun NavigationButton(
navController: NavController,
title: String,
targetRoute: Any,
popUpToRoute: Any? = null,
popUpToInclusive: Boolean,
singleTop: Boolean,
) {
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
navController.navigate(
route = targetRoute
) {
popUpToRoute?.let {
popUpTo(
route = it
) {
inclusive = popUpToInclusive
}
}
launchSingleTop = singleTop
}
}
) {
Text("Navigate to $title")
}
}
@Composable
private fun CheckBoxWithText(
modifier: Modifier = Modifier,
title: String,
enabled: Boolean = true,
checked: Boolean,
onCheckChange: (Boolean) -> Unit,
) {
Row(
modifier = modifier
.clickable(
enabled = enabled
) {
onCheckChange(checked.not())
}
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(checked = checked, onCheckedChange = null, enabled = enabled)
Spacer(Modifier.width(16.dp))
Text(title)
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... navigation
Динамически настраиваемый график с типобезопасной навигацией Jetpack Compose. ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Общая модель представления с типобезопасной навигацией в многомодульном проекте
Anonymous » » в форуме Android - 0 Ответы
- 11 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Неожиданное нулевое значение в типобезопасной навигации Jetpack Compose
Anonymous » » в форуме Android - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-