Instantly share code, notes, and snippets.
Created
April 4, 2022 13:19
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save stdpmk/3051bae2347cc5ee19ae20299a19c90f to your computer and use it in GitHub Desktop.
compose_conditional_nav
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Как лучше в Compose реализовать условную навигацию? | |
| // Есть какие-то патерны? | |
| // В данном примере условная навигация в методе | |
| // navigateToB | |
| // В зависимости от экрана на котором мы сейчас находимся, делаем тот или иной переход | |
| // Граф | |
| @Composable | |
| fun MainNavGraph2( | |
| modifier: Modifier = Modifier, | |
| ) { | |
| val navController: NavHostController = rememberNavController() | |
| NavHost( | |
| navController = navController, | |
| startDestination = "A", | |
| modifier = modifier | |
| ) { | |
| composable("A") { | |
| // Главный экран с 3-мя кнопками для теста навигации | |
| ScreenA(navController = navController) | |
| } | |
| composable("B") { | |
| // B - текущий, C - куда переходим | |
| Screen(screen = "B", toScreen = "C", | |
| navigateToScreen = { | |
| navigateToC(navController) | |
| }, | |
| color = Color.Red, | |
| ) | |
| } | |
| composable("C") { | |
| Screen(screen = "C", toScreen = "B", | |
| navigateToScreen = { | |
| navigateToB(navController) | |
| }, | |
| color = Color.Blue | |
| ) | |
| } | |
| composable("D") { | |
| // Тут показываем диалог, а уже из него (код ниже) переходим в B | |
| Screen(screen = "D", toScreen = "dialog", | |
| navigateToScreen = { | |
| navigateToDialogD(navController) | |
| }, | |
| color = Color.Yellow | |
| ) | |
| } | |
| dialog("dialogD") { | |
| DialogD( | |
| onOk = { | |
| navigateToB(navController) | |
| }, | |
| onDismissed = { | |
| navController.popBackStack() | |
| } | |
| ) | |
| } | |
| } | |
| } | |
| // Начальный экран | |
| @Composable | |
| fun ScreenA( | |
| navController: NavController, | |
| ) { | |
| Box( | |
| modifier = Modifier.fillMaxSize(), | |
| contentAlignment = Alignment.Center, | |
| ) { | |
| Column { | |
| Button(onClick = { | |
| navigateToB(navController) | |
| }) { | |
| Text(text = "A->B") | |
| } | |
| Spacer(Modifier.padding(top = 5.dp)) | |
| Button(onClick = { | |
| navigateToBC(navController) | |
| }) { | |
| Text(text = "A->(B->C). Open subchain B->C") | |
| } | |
| Spacer(Modifier.padding(top = 5.dp)) | |
| Button(onClick = { | |
| navigateToD(navController) | |
| }) { | |
| Text(text = "A->D") | |
| } | |
| } | |
| } | |
| } | |
| // Навигация вынесена в отдельные top level функции | |
| // Top level function | |
| private fun navigateToB(navController: NavController) { | |
| val currentRoute = navController.currentBackStackEntry?.destination?.route | |
| when(currentRoute) { | |
| "A" -> { | |
| navController.navigate("B") | |
| } | |
| "C" -> { | |
| navController.navigate("B") { | |
| popUpTo(0) | |
| } | |
| } | |
| "D" -> { | |
| navController.navigate("dialogD") | |
| } | |
| "dialogD" -> { | |
| navController.navigate("B") { | |
| popUpTo(0) | |
| } | |
| } | |
| } | |
| } | |
| private fun navigateToBC(navController: NavController) { | |
| val currentRoute = navController.currentBackStackEntry?.destination?.route | |
| if (currentRoute == "A") { | |
| navController.navigate("B") | |
| navController.navigate("C") | |
| } | |
| } | |
| private fun navigateToD(navController: NavController) { | |
| navController.navigate("D") | |
| } | |
| private fun navigateToC(navController: NavController) { | |
| navController.navigate("C") | |
| } | |
| private fun navigateToDialogD(navController: NavController) { | |
| navController.navigate("dialogD") | |
| } | |
| @Composable | |
| fun Screen( | |
| screen: String, | |
| toScreen: String, | |
| color: Color = Color.Black, | |
| navigateToScreen: () -> Unit = {} | |
| ) { | |
| Box( | |
| modifier = Modifier | |
| .fillMaxSize() | |
| .background(color), | |
| contentAlignment = Alignment.Center, | |
| ) { | |
| Column { | |
| Text(text = screen) | |
| Button(onClick = { navigateToScreen() }) { | |
| Text(text = "Go to $toScreen") | |
| } | |
| } | |
| } | |
| } | |
| @Composable | |
| fun DialogD( | |
| onDismissed: () -> Unit = {}, | |
| onOk: () -> Unit = {}, | |
| ) { | |
| AlertDialog( | |
| buttons = { | |
| Button(onClick = { | |
| onOk() | |
| }) { | |
| Text(text = "Ok") | |
| } | |
| }, | |
| title = { | |
| Text(text = "DialogD") | |
| }, | |
| text = { | |
| Text(text = "Go to B") | |
| }, | |
| onDismissRequest = { | |
| onDismissed() | |
| }) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment