Compose Unstyled 2.0 is out! Check the official announcement blog ->

Navigation Bar

Bottom navigation bars for switching between top-level destinations.

Use a navigation bar when users need to move between a small set of primary destinations.

View on GitHub
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Bell
import com.composables.icons.lucide.Heart
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.icons.lucide.Search
import com.composables.ui.components.Icon
import com.composables.ui.components.NavigationBar
import com.composables.ui.components.NavigationBarItem

@Composable
fun NavigationBarExample() {
    var selectedItem by remember { mutableStateOf("Feed") }
    NavigationBar(modifier = Modifier.fillMaxWidth()) {
        NavigationBarItem(
            selected = selectedItem == "Feed",
            onClick = { selectedItem = "Feed" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Heart, contentDescription = "Feed", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Search",
            onClick = { selectedItem = "Search" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Search, contentDescription = "Search", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Create",
            onClick = { selectedItem = "Create" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Plus, contentDescription = "Create", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Activity",
            onClick = { selectedItem = "Activity" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Bell, contentDescription = "Activity", modifier = Modifier.size(20.dp))
        }
    }
}

Installation

implementation("com.composables:ui:0.1.0")

Examples

Disabled items

View on GitHub
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Bell
import com.composables.icons.lucide.Heart
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.icons.lucide.Search
import com.composables.ui.components.Icon
import com.composables.ui.components.NavigationBar
import com.composables.ui.components.NavigationBarItem

@Composable
fun DisabledNavigationBarExample() {
    var selectedItem by remember { mutableStateOf("Feed") }
    NavigationBar(modifier = Modifier.fillMaxWidth()) {
        NavigationBarItem(
            selected = selectedItem == "Feed",
            onClick = { selectedItem = "Feed" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Heart, contentDescription = "Feed", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Search",
            onClick = { selectedItem = "Search" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Search, contentDescription = "Search", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = false,
            onClick = { selectedItem = "Create" },
            enabled = false,
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Plus, contentDescription = "Create", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = false,
            onClick = { selectedItem = "Activity" },
            enabled = false,
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Bell, contentDescription = "Activity", modifier = Modifier.size(20.dp))
        }
    }
}

Custom insets

View on GitHub
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Bell
import com.composables.icons.lucide.Heart
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.icons.lucide.Search
import com.composables.ui.components.Icon
import com.composables.ui.components.NavigationBar
import com.composables.ui.components.NavigationBarItem

@Composable
fun CustomInsetsNavigationBarExample() {
    var selectedItem by remember { mutableStateOf("Feed") }
    NavigationBar(
        modifier = Modifier.fillMaxWidth(),
        windowInsets = WindowInsets(bottom = 32.dp),
    ) {
        NavigationBarItem(
            selected = selectedItem == "Feed",
            onClick = { selectedItem = "Feed" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Heart, contentDescription = "Feed", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Search",
            onClick = { selectedItem = "Search" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Search, contentDescription = "Search", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Create",
            onClick = { selectedItem = "Create" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Plus, contentDescription = "Create", modifier = Modifier.size(20.dp))
        }
        NavigationBarItem(
            selected = selectedItem == "Activity",
            onClick = { selectedItem = "Activity" },
            modifier = Modifier.weight(1f),
        ) {
            Icon(Lucide.Bell, contentDescription = "Activity", modifier = Modifier.size(20.dp))
        }
    }
}

API Reference

A bottom navigation bar container.

@Composable
fun NavigationBar(
    modifier: Modifier = Modifier,
    windowInsets: WindowInsets = navigationBarWindowInsets(),
    content: @Composable RowScope.() -> Unit,
)
Parameter Type Description
modifier Modifier Modifier applied to the component.
windowInsets WindowInsets Insets applied around the navigation bar content.
content @Composable RowScope.() -> Unit Composable content displayed by the component.

A single destination action inside a navigation bar.

@Composable
fun NavigationBarItem(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = RoundedCornerShape(8.dp),
    content: @Composable () -> Unit,
)
Parameter Type Description
selected Boolean Whether the navigation item is currently selected.
onClick () -> Unit Called when the navigation item is activated.
modifier Modifier Modifier applied to the component.
enabled Boolean Whether the navigation item can be interacted with.
shape Shape Shape used for the selected navigation item background.
content @Composable () -> Unit Composable content displayed by the component.