0

I have a code which calculates if bottom navigation bar should be visible, but once I got to specific screen the navigation resets to first home tab. I guess recomoposition occurs for whole Scaffold, but can't see why. I'm using new type safe compose navigation if that matters.

Here is a relevant code:

@Composable
fun HomeNav() {
    val navController = rememberNavController()

    var shouldShowBottomBar by rememberSaveable {
        mutableStateOf(true)
    }

    var selectedItemIndex by rememberSaveable {
        mutableIntStateOf(0)
    }

    LaunchedEffect(key1 = navController) {
        navController.addOnDestinationChangedListener { _, destination, _ ->
            shouldShowBottomBar = !destination.hasRoute(Details::class)

            if (destination.hasRoute(Home::class)) {
                selectedItemIndex = 0
            }
        }
    }

    Scaffold(
        bottomBar = {
            AnimatedVisibility(visible = shouldShowBottomBar) {
                NavigationBar {
                    bottomNavItems.forEachIndexed { index, item ->
                        NavigationBarItem(
                            selected = selectedItemIndex == index,
                            onClick = {
                                selectedItemIndex = index
                                navController.navigate(item.destination) {
                                    popUpTo(Home) {
                                        saveState = true
                                    }
                                    launchSingleTop = true
                                    restoreState = true
                                }
                            },
                            ...
                        )
                    }
                }
            }
        }
    ) { innerPadding ->
        NavHost(
            modifier = Modifier.padding(innerPadding),
            navController = navController,
            startDestination = HomeGraph
        ) {
            homeNavGraph(navController)
        }
    }
}
5
  • screen the navigation resets to first home tab Didn't understand how this is related to the question. I mean there's code to set the index to zero right?
    – gtxtreme
    Commented Jul 10 at 10:38
  • I don't set index to zero. In the code from the question, if you navigate to Details screen that means shouldShowBottomBar is true, and Details screen is presented for like 200ms and immediately it navigates up to Home screen. In the mean time, I tried to use if (shouldShowBottomBar) condition inside NavigationBar composable, and it doesn't navigate up to Home anymore, and instead it hides bottom navigation items but the background of the NavigationBar is visible. The question really is how to hide bottom navigation, and the same happens for TopAppBar.
    – BorkoC
    Commented Jul 10 at 12:29
  • Have you tried to set breakpoints to all the navController.navigate() calls in your code? Then you can see which one is triggering the unwanted navigation to the Home destination. Also set a breakpoint on the line selectedItemIndex = 0 to see when it gets called. developer.android.com/studio/debug
    – BenjyTec
    Commented Jul 10 at 14:26
  • Only navController.navigate(Details) is called when I debug the code, but it still navigates up to Home, I suspected because of recomposition. And that selectedItemIndex = 0 is only used to select first item in BottomNavigation when I use back gesture from other screens, I commented out that code now for testing, there is no difference. So you guys think that my code looks fine? I was hoping for some obvious mistake on my side. :)
    – BorkoC
    Commented Jul 10 at 14:34
  • I created new project with the same code and it works. There might be some difference but I honestly can't see it and it's a short code. Thank you all.
    – BorkoC
    Commented Jul 12 at 11:38

0