Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding spacing between BottomNavigationItem's icon & label

I'm trying to build out my Bottom navigation like this:

@Composable
fun BottomNavBar(navController: NavController) {
    Column(
        Modifier.background(colorResource(id = R.color.pastel_orange_white))
    ) {
        BottomNavigation(
            modifier = Modifier
                .defaultMinSize(minHeight = 70.dp),
            backgroundColor = colorResource(id = R.color.bottom_nav_dark)
        ) {
            val navItems = arrayOf(
                BottomNavItem(
                    stringResource(id = R.string.title_home),
                    R.drawable.ic_home,
                    Screen.Home.route
                ),
                BottomNavItem(
                    stringResource(id = R.string.subjects_title),
                    R.drawable.ic_subject,
                    Screen.Subjects.route
                ),
                BottomNavItem(
                    stringResource(id = R.string.grades_title),
                    R.drawable.ic_grade,
                    Screen.Grades.route
                ),
                BottomNavItem(
                    "H/W",
                    R.drawable.ic_assignments,
                    Screen.Assignments.route
                )
            )
            // observe the backstack
            val navBackStackEntry by navController.currentBackStackEntryAsState()
            // observe current route to change the icon
            // color,label color when navigated
            val currentRoute = navBackStackEntry?.destination?.route
            navItems.forEach { navItem ->
                BottomNavigationItem(
                    selected = currentRoute == navItem.route,
                    onClick = {
                        navController.navigate(navItem.route)
                    },
                    icon = {
                        Box(
                            Modifier
                                .width(70.dp)
                                .height(30.dp)
                                .background(
                                    colorResource(id = if (currentRoute == navItem.route) R.color.bottom_nav_light else R.color.bottom_nav_dark),
                                    RoundedCornerShape(32.dp)
                                ),
                            contentAlignment = Alignment.Center
                        ) {
                            Icon(
                                painter = painterResource(id = navItem.icon),
                                contentDescription = navItem.label,
                                tint = colorResource(id = R.color.black)
                            )
                        }
                    },
                    label = {
                        Text(text = navItem.label, fontSize = 14.sp)
                    },
                    alwaysShowLabel = true,
                    selectedContentColor = colorResource(id = R.color.black),
                    unselectedContentColor = colorResource(id = R.color.black)
                )
            }
        }
    }
}

I need to add some extra space between the label and the icon parts, since I'm applying a small background color to the selected item. I tried with paddings, column arrangements, etc. but didn't find something that actually affected the spacing. Any pointers?

like image 794
Stelios Papamichail Avatar asked Jan 19 '26 18:01

Stelios Papamichail


2 Answers

I don't think you can do it using a BottomNavigationItem. The Material Design Library for Compose follows the Material Design Specification as you can see here.

But you don't need to use a BottomNavigationItem to display the items in your BottomAppBar. You can use any composable, like below:

Column(
    horizontalAlignment = Alignment.CenterHorizontally,
    modifier = Modifier
        .weight(1f)
        .clickable {
            navController.navigate(navItem.route)
        }) {
    val color =
        if (currentRoute == navItem.route) 
            LocalContentColor.current 
        else 
            LocalContentColor.current.copy(alpha = ContentAlpha.medium)
    Icon(
        painter = painterResource(id = navItem.icon), 
        navItem.label, 
        tint = color
    )
    // Set the space that you want...
    Spacer(modifier = Modifier.height(4.dp))
    Text(text = navItem.label, color = color, fontSize = 12.sp)
}

However, as I mentioned above, the library follows the Material Design specs, which define the BottomAppBar's height as 56dp. Therefore, if you want something more custom, you need to it by your own (using a Row, for instance).

like image 123
nglauber Avatar answered Jan 21 '26 06:01

nglauber


Add padding to your icon

     items.forEach { item ->
        BottomNavigationItem(
            icon = {
                Icon(
                    modifier=Modifier.padding(6.dp), //add this line
                    painter = painterResource(id = item.icon),
                    tint = MaterialTheme.colorScheme.onSurface,
                    contentDescription = stringResource(id = item.title)
                )
            },

            label = {
                Text(
                     text = stringResource(id = item.title),
                    style = MaterialTheme.typography.labelSmall,
                    color = MaterialTheme.colorScheme.onSurface
                )
            },
            selected = currentRoute == item.route,
            
        )
    }
like image 28
yousef Abbdolzadeh Avatar answered Jan 21 '26 07:01

yousef Abbdolzadeh