Skip to main content
NavigationBar provides a bottom navigation bar for switching between primary destinations in an app. It supports icons, labels, and selection states with smooth animations.
modifier
Modifier
default:"Modifier"
Modifier to be applied to the navigation bar
containerColor
Color
default:"NavigationBarDefaults.containerColor"
Background color of the navigation bar. Defaults to AppTheme.colors.background
contentColor
Color
default:"contentColorFor(containerColor)"
Color for content inside the navigation bar
windowInsets
WindowInsets
default:"NavigationBarDefaults.windowInsets"
Window insets for system bars
content
@Composable RowScope.() -> Unit
required
Content of the navigation bar, typically NavigationBarItem components
selected
Boolean
required
Whether this item is currently selected
onClick
() -> Unit
required
Callback invoked when the item is clicked
icon
@Composable () -> Unit
required
Icon to display for this item
modifier
Modifier
default:"Modifier"
Modifier to be applied to the item
enabled
Boolean
default:"true"
Whether the item is enabled
label
@Composable (() -> Unit)?
default:"null"
Optional text label to display below the icon
alwaysShowLabel
Boolean
default:"true"
Whether to always show the label or only when selected
colors
NavigationBarItemColors
default:"NavigationBarItemDefaults.colors()"
Colors for icon and text in different states
textStyle
TextStyle
default:"NavigationBarItemDefaults.textStyle()"
Text style for the label. Defaults to AppTheme.typography.label2
interactionSource
MutableInteractionSource
default:"MutableInteractionSource()"
Source of interactions for the item

Usage Examples

Basic Navigation Bar

var selectedItem by remember { mutableStateOf(0) }

NavigationBar {
    NavigationBarItem(
        selected = selectedItem == 0,
        onClick = { selectedItem = 0 },
        icon = {
            Icon(
                imageVector = Icons.Default.Home,
                contentDescription = "Home"
            )
        },
        label = { Text("Home") }
    )
    
    NavigationBarItem(
        selected = selectedItem == 1,
        onClick = { selectedItem = 1 },
        icon = {
            Icon(
                imageVector = Icons.Default.Search,
                contentDescription = "Search"
            )
        },
        label = { Text("Search") }
    )
    
    NavigationBarItem(
        selected = selectedItem == 2,
        onClick = { selectedItem = 2 },
        icon = {
            Icon(
                imageVector = Icons.Default.Person,
                contentDescription = "Profile"
            )
        },
        label = { Text("Profile") }
    )
}
var selectedItem by remember { mutableStateOf(0) }

NavigationBar {
    NavigationBarItem(
        selected = selectedItem == 0,
        onClick = { selectedItem = 0 },
        icon = {
            Icon(
                imageVector = Icons.Default.Home,
                contentDescription = "Home"
            )
        }
    )
    
    NavigationBarItem(
        selected = selectedItem == 1,
        onClick = { selectedItem = 1 },
        icon = {
            Icon(
                imageVector = Icons.Default.Favorite,
                contentDescription = "Favorites"
            )
        }
    )
    
    NavigationBarItem(
        selected = selectedItem == 2,
        onClick = { selectedItem = 2 },
        icon = {
            Icon(
                imageVector = Icons.Default.Settings,
                contentDescription = "Settings"
            )
        }
    )
}

Show Labels Only When Selected

var selectedItem by remember { mutableStateOf(0) }

NavigationBar {
    NavigationBarItem(
        selected = selectedItem == 0,
        onClick = { selectedItem = 0 },
        icon = { Icon(Icons.Default.Home, null) },
        label = { Text("Home") },
        alwaysShowLabel = false
    )
    
    NavigationBarItem(
        selected = selectedItem == 1,
        onClick = { selectedItem = 1 },
        icon = { Icon(Icons.Default.Search, null) },
        label = { Text("Search") },
        alwaysShowLabel = false
    )
}

Custom Colors

NavigationBar(
    containerColor = Color(0xFF1E1E1E),
    contentColor = Color.White
) {
    NavigationBarItem(
        selected = true,
        onClick = { },
        icon = { Icon(Icons.Default.Home, null) },
        label = { Text("Home") },
        colors = NavigationBarItemDefaults.colors(
            selectedIconColor = Color(0xFF00BCD4),
            selectedTextColor = Color(0xFF00BCD4),
            unselectedIconColor = Color.White.copy(alpha = 0.6f),
            unselectedTextColor = Color.White.copy(alpha = 0.6f)
        )
    )
}

With Badge

NavigationBarItem(
    selected = selectedItem == 1,
    onClick = { selectedItem = 1 },
    icon = {
        BadgedBox(
            badge = {
                Badge { Text("3") }
            }
        ) {
            Icon(Icons.Default.Notifications, null)
        }
    },
    label = { Text("Notifications") }
)

Disabled Item

NavigationBarItem(
    selected = false,
    onClick = { },
    enabled = false,
    icon = { Icon(Icons.Default.Lock, null) },
    label = { Text("Locked") }
)

Complete Example with Scaffold

enum class Screen {
    HOME, SEARCH, FAVORITES, PROFILE
}

@Composable
fun MainScreen() {
    var currentScreen by remember { mutableStateOf(Screen.HOME) }
    
    Scaffold(
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    selected = currentScreen == Screen.HOME,
                    onClick = { currentScreen = Screen.HOME },
                    icon = { Icon(Icons.Default.Home, null) },
                    label = { Text("Home") }
                )
                
                NavigationBarItem(
                    selected = currentScreen == Screen.SEARCH,
                    onClick = { currentScreen = Screen.SEARCH },
                    icon = { Icon(Icons.Default.Search, null) },
                    label = { Text("Search") }
                )
                
                NavigationBarItem(
                    selected = currentScreen == Screen.FAVORITES,
                    onClick = { currentScreen = Screen.FAVORITES },
                    icon = { Icon(Icons.Default.Favorite, null) },
                    label = { Text("Favorites") }
                )
                
                NavigationBarItem(
                    selected = currentScreen == Screen.PROFILE,
                    onClick = { currentScreen = Screen.PROFILE },
                    icon = { Icon(Icons.Default.Person, null) },
                    label = { Text("Profile") }
                )
            }
        }
    ) { paddingValues ->
        Box(modifier = Modifier.padding(paddingValues)) {
            when (currentScreen) {
                Screen.HOME -> HomeScreen()
                Screen.SEARCH -> SearchScreen()
                Screen.FAVORITES -> FavoritesScreen()
                Screen.PROFILE -> ProfileScreen()
            }
        }
    }
}

Styling Options

NavigationBar(
    containerColor = AppTheme.colors.surface,
    contentColor = AppTheme.colors.onSurface
) { }

Item Colors

NavigationBarItemDefaults.colors(
    selectedIconColor: Color = AppTheme.colors.onBackground,
    selectedTextColor: Color = AppTheme.colors.onBackground,
    unselectedIconColor: Color = AppTheme.colors.onBackground.copy(alpha = 0.65f),
    unselectedTextColor: Color = AppTheme.colors.onBackground.copy(alpha = 0.65f),
    disabledIconColor: Color = AppTheme.colors.onBackground.copy(alpha = 0.3f),
    disabledTextColor: Color = AppTheme.colors.onBackground.copy(alpha = 0.3f)
)

Features

  • Smooth Animations: Icon and label animate during selection with 100ms duration
  • Adaptive Layout: Items automatically distribute available width
  • Window Insets: Proper handling of system navigation bars
  • Accessibility: Full semantic support with Role.Tab
  • RTL Support: Correct layout in right-to-left languages
  • State Management: Built-in selection state handling
  • Custom Typography: Configurable text style for labels

Design Guidelines

  1. Item Count: Use 3-5 navigation items for optimal usability
  2. Icons: Use clear, recognizable icons
  3. Labels: Keep labels short (1-2 words)
  4. Selection: Always have one item selected
  5. Disabled States: Use sparingly

Constants

  • Height: 80dp (NavigationBarDefaults.NavigationBarHeight)
  • Horizontal Padding: 8dp per item
  • Vertical Padding: 18dp per item
  • Animation Duration: 100ms

Source Reference

NavigationBar component implementation: components-lab/src/commonMain/kotlin/com/nomanr/lumo/ui/components/NavigationBar.kt

Build docs developers (and LLMs) love