https://kotlinlang.org logo
#compose
Title
# compose
s

star_zero

05/01/2022, 2:23 AM
How can I do if BottomNavigation has a common screen? • tab1: ScreenA -> ScreenB -> ScreenCommon • tab2: ScreenC -> ScreenD -> ScreenCommon
I tried the following code, but when I display ScreenCommon, the BottomNavigationItem is deselected.
Copy code
NavHost(navController = navController, startDestination = "tab1") {
    navigation(startDestination = "screen_a", route = "tab1") {
        composable("screen_a") { /* */ }
        composable("screen_b") { /* */ }
    }
    navigation(startDestination = "screen_c", route = "tab2") {
        composable("screen_c") { /* */ }
        composable("screen_d") { /* */ }
    }
    composable("screen_common") { /* */ }
}
BottomNavigationItem is implemented as follows. Same as the document.
Copy code
BottomNavigationItem(
    selected = currentDestination?.hierarchy?.any { it.route == tab.route } == true,
    // ...
)
i

Ian Lake

05/01/2022, 3:44 AM
The documentation uses the current destination and its location in the navigation graph to determine what tab is selected. It sounds like the code is doing exactly what you told it to do.
If you want to track the last selected bottom nav item and use that as the source of truth for what tab is selected (and not use the current destination for that source of truth), there's nothing stopping you from writing that code
s

star_zero

05/01/2022, 4:18 AM
Ah, I see. I’ll try it. Thank you.
Fixed
Copy code
BottomNavigation {
    var selectedIndex by rememberSaveable { mutableStateOf(0) }

    tabs.forEachIndexed { index, tab ->
        BottomNavigationItem(
            selected = selectedIndex == index,
            onClick = {
                if (selectedIndex == index) {
                    (navController.findDestination(tab.route) as? NavGraph)?.let {
                        navController.popBackStack(it.startDestinationId, false)
                    }
                } else {
                    navController.navigate(tab.route) {
                        popUpTo(navController.graph.id) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                    selectedIndex = index
                }
            },
            icon = {
                Icon(imageVector = tab.icon, contentDescription = null)
            },
            label = {
                Text(text = tab.label)
            },
        )
    }
}
3 Views