Динамически настраиваемый график с типобезопасной навигацией Jetpack Compose.Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Динамически настраиваемый график с типобезопасной навигацией Jetpack Compose.

Сообщение Anonymous »

Работает ли 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»