Compose BottomNavigation padding

1.2k Views Asked by At

Im trying to properly apply a bottom window inset on the BottomNavigation composable. I have an edge to edge scaffold it looks like that: enter image description here

When using:

modifier.navigationBarsPadding()

On the bottom navigation im getting the following: enter image description here

I'm trying to achieve the following: enter image description here

         Scaffold(
            modifier = Modifier
                .background(brush = NanitColors.blueGradient),
            topBar = {
                topBar()
            },
            bottomBar = {
                if (shouldShowBottomBar) {
                    BottomNavigationBar(navController)
                }
            },
            scaffoldState = scaffoldState,
            drawerContent = {
                Drawer { route ->
                    scope.launch {
                        scaffoldState.drawerState.close()
                    }
                    navController.navigate(route.route) {
                        popUpTo(navController.graph.startDestinationId)
                        launchSingleTop = true
                    }
                    currentDestination = route
                }
            },
            drawerGesturesEnabled = scaffoldState.drawerState.isOpen,
        ) { innerPadding ->
            NavigationHost(navController = navController, modifier = Modifier.padding(innerPadding))
        }
    
     val topBar: @Composable () -> Unit = {
            MainToolbar(
                modifier = modifier.statusBarsPadding(),
                title = title ?: "",
                onMenuClicked = {
                    scope.launch {
                        scaffoldState.drawerState.open()
                    }
                }
            )
        }

 BottomNavigation(
        modifier = modifier.navigationBarsPadding()
    ) {
        items.forEach { item ->
            BottomNavigationBarItem(
                item = item,
                isSelected = selectedItem?.route == item.route,
                onSelectedChange = { onSelectedItemChange(item) }
            )
        }
    }
2

There are 2 best solutions below

2
AliSh On

You can use accompanist systemuicontroller to set color to navigation bar, use default color for other screens and add color just for the screen you need:

@Composable
fun AppTheme(
    systemBarColor: Color = MaterialTheme.colors.background,
    content: @Composable () -> Unit,
) {
   ...

    SideEffect {
        systemUiController.setNavigationBarColor(
            color = systemBarColor,
            darkIcons = useDarkIcons
        )
    }
}
0
Timo Drick On

If you are using Material3 than you could use the BottomAppBar(). This component supports WindowInsets. So it will automatically respect the system navigation bar and draws the background behind it.

Scaffold(
    ...
    bottomBar = {
        if (shouldShowBottomBar) {
            BottomAppBar(
                // you could of course also use WindowInsets.navigationBars
                windowInsets = WindowInsets.safeDrawing.only(
                    WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom
                )
            ) {
                ...
            }
        }
    },
    ...
)