Search code examples
navigationandroid-jetpack-compose

Navigation topAppBar with BottomNavigation


I have problem with showing back button in topAppBar. I have bottomNavigation for Home and favorite bikes. When i want to show details of the bike I want back arrow to go back.

BottomNavGraph:

NavHost(
    navController =navController,
    startDestination = Screen.Home.route
){
    composable(route = Screen.Home.route){
        HomeScreen(navController = navController)
    }
    composable(route = Screen.Favorite.route){
        FavoriteScreen(navController = navController)
    }
    composable(route = Screen.Details.route){
        val bike = navController.previousBackStackEntry?.savedStateHandle?.get<Bike>("bike")

        bike?.let{
            BikeDetaliScreen(navController = navController, movie)
        }

    }

And TopAppBar:

if(navController.previousBackStackEntry != null){
        TopAppBar(
            title = {
                Box(modifier = Modifier.fillMaxWidth()
                ) {
                    Image(
                        painterResource(
                            id = R.drawable.bike_logo
                        ),
                        "Logo picture",
                        modifier = Modifier
                            .size(130.dp)
                            .align(Alignment.Center)
                    )
                }
            },
            backgroundColor = Color(0xFF0B253F)
        )
    }

Problem is I want to have back arrow only in details screen, not in home or favorite. But when I use previousBackStackEntry != null somethimes favorite screen has arrow because it has homeScreen in stack.


Solution

  • You can observe the current back stack entry and show/hide the back button accordingly.

    // When you navigate to another screen, this value is updated.
    val currentRoute = navController
        .currentBackStackEntryFlow
        .collectAsState(initial = navController.currentBackStackEntry)
    
    val showBackButton = when (currentRoute.value?.destination?.route) {
        Screen.Home.route -> false
        else -> true
    }
    
    TopAppBar(
        ...
        navigationIcon = {
            if (showBackButton) {
                IconButton(
                    onClick = { ... }
                ) { Icon(Icons.Default.ArrowBack, "Back") }
            }
        }
    )