How to navigate to a non bottom bar screen with jetpack compose?
Asked Answered
P

2

20

So i have an app in compose that has startDestination set as a screen with scaffold with bottom nav bar having 3 items and top app bar, i am able to navigate through the 3 bottom navigation tabs. But suppose i want to click on a card in one of the bottom tab screen which should open a details screen without the bottom bar and app bar (Since Navhost is inside the scaffold, bottom and top bars show up on details screen too), what is the right way to do that? Currently i have tried the following ways:-

1. Starting the details screen in a new activity.

2. Using currentDestination route as state to conditionally hide bottom and app bar for details screen route.

Both work but, the problem with first approach is that, it isn't recommended to use multiple activity with jetpack navigation and rather we should stick to a single activity, it also further breaks the navigation if in case i want to move from details to another screen. The problem with second approach is that hiding and showing bottom/top bars create very bad transition between the screens and app doesn't feel smooth.

Hence, i am looking for an appropriate way to handle this as per the guidelines, although i couldn't find any info on this.

Update

I went with showing/hiding the bottom and app bar based on routes, turns out that bad and laggy animation i was facing was because i was running a debug app, with a release app with minifyEnabled true (R8) ,the transitions are very smooth and natural, as i wanted them.

Also it turns out, as per Google's official compose sample app JetSnack , this is the appropriate way of achieving navigation from a bottombar screen to a non-bottombar screen. Thanks to @vitidev for pointing it out in the comments.

Pigtail answered 1/6, 2022 at 0:12 Comment(4)
"hiding and showing bottom/top bars create very bad transition between the screens and app doesn't feel smooth." - but you are in control over what transition you use for your bottom/top bars and their timing, so any 'very bad transition' is caused by your transition code (or the lack thereof). Can you be specific on what transition you want (precisely, how do you want the bottom bar/top bar to enter/leave the screen and when, in relation to the NavHost's transition animation) and what code you've already written to try to implement that transition?Antiperspirant
@Antiperspirant Hi, i am currently not using any transition, i have just wrapped the TopAppBar & BottomBar component calls in scaffold in a if block that is true only when route is either of the bottom nav items. I have also tried using AnimatedVisibility, but the kind of transition it created didn't feel natural. I don't want it to appear like the bottom & top bars are sliding in & out on show & hide respectively, instead i would like new screen to appear like how a new activity would or it should be as subtle as the transition between the content part of the scaffold.Pigtail
'Jetsnack' from official compose samples uses second option - conditionally hide bottom bar for routes that not exists in bottom barBaughman
@vitidev 's comment about hiding the bottom bar is actually not the case. In fact, in the JetSnack sample, the bottom bar is included and repeated in composables that are supposed to have a bottom bar and excluded in other composables. and about the sentence 'Since the NavHost is inside the scaffold, the bottom and top bars show up on the details screen too' , the NavHost is invoked in the root.Mediatize
A
2

One way you can do this is to have to navControllers in the your navigation. One for MainNavigation(navigation outside the bottom nav bar) and the other for navigation inside the bottomNavBar.

    @Composable
fun MainNavigation() {
    val navController = rememberNavController()
    val navControllerBottomBar = rememberNavController()

    NavHost(navController = navController, startDestination ="") {
        composable("login") {
            LoginScreen()
        }
       
        composable("bottomBarNav") {
            BottomBarNavigation(navController = navControllerBottomBar)
        }

      
    }

}

// BottomBarNavigation

@Composable
fun BottomBarNavigation(navController: NavHostController) {

    Scaffold(
        bottomBar = {}
    ) { innerPadding ->
        val modifier = Modifier.padding(innerPadding)
        NavHost(navController, startDestination = "Home", modifier = modifier) {
        composable("home") { HomeScreen() }
      }
    }
}

I dont know if this is recommended or has downsides or not, there are not a lot of information out there on this but it works

Anabolite answered 7/8, 2023 at 21:30 Comment(0)
N
0

You can use a nested Navigation Graph:

  • one principal graph according to your BottomBar
  • one nested graph inside each screen you want to go further

https://developer.android.com/jetpack/compose/navigation#nested-nav

Nonie answered 1/6, 2022 at 12:26 Comment(1)
But even if i do nested graphs, the NavHost still will exist inside scaffold right and hence further screens will still render with bottom and app bar.Pigtail

© 2022 - 2025 — McMap. All rights reserved.