Material 3 Navigation Rail in Android with Developer Documentation

Material 3 Navigation Rail 

Overview

Navigation rails provide ergonomic access to primary app destinations.

Material 3 Navigation Rails, using NavigationRailView, support 3–7 destinations in collapsed mode and unlimited items in expanded mode, replacing navigation drawers on tablet and desktop screens. They include optional headers, badges, and labels, adhering to Material Design guidelines. This guide covers implementation, accessibility, and theming.

Using Navigation Rails

  • Add Material Components for Android library dependency
  • Use NavigationRailView with a menu resource for destinations
  • Apply Theme.Material3.* or Theme.Material3Expressive.* theme for styling
  • Support collapsed (default) and expanded modes

Accessibility

  • Set android:title on menu items for TalkBack to announce destinations
  • Use labelVisibilityMode to control label visibility (LABEL_VISIBILITY_AUTO, SELECTED, LABELED, UNLABELED)
  • Ensure icons and badges have sufficient contrast

Behavior and Configuration

  • Configure menus via XML, add headers (e.g., FAB) or badges
  • Handle item selection with setOnItemSelectedListener and reselection with setOnNavigationItemReselectedListener
  • Use expand()/collapse() for dynamic behavior
  • Support submenus in expanded mode
      
val navigationRail = findViewById<NavigationRailView>(R.id.navigation_rail)
navigationRail.setOnItemSelectedListener { item ->
    when (item.itemId) {
        R.id.alarms -> { /* Handle alarms */ true }
        R.id.schedule -> { /* Handle schedule */ true }
        R.id.timers -> { /* Handle timers */ true }
        else -> false
    }
}
navigationRail.setOnNavigationItemReselectedListener { item ->
    when (item.itemId) {
        R.id.alarms -> { /* Handle alarms reselection */ }
        R.id.schedule -> { /* Handle schedule reselection */ }
    }
}
      
    

Navigation Rail Anatomy


Component Description Collapsed State Expanded State
Container 80dp wide (default), 0dp elevation, holds content Shows 3–7 items Shows unlimited items, including submenus
Header Optional FAB or logo, 8dp bottom margin Visible if set Visible if set
Icons/Labels Destinations with icons (24dp) and optional labels Limited to 7, labels per labelVisibilityMode All items shown, labels typically visible
Active Indicator Highlights active item, 56dp wide, 32dp high Compact, rounded shape Expanded width, wraps content
Badges Optional counts/status, large/small variants Visible if set Visible if set

Navigation Rail Example

  • Compact navigation for tablet/desktop screens
  • Supports badges, headers, and expansion

Example

      
<com.google.android.material.navigationrail.NavigationRailView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_rail"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    app:headerLayout="@layout/navigation_rail_fab"
    app:menu="@menu/navigation_rail_menu"/>
      
    
      
<!-- res/menu/navigation_rail_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/alarms"
        android:enabled="true"
        android:icon="@drawable/icon_alarm"
        android:title="@string/alarms"/>
    <item
        android:id="@+id/schedule"
        android:enabled="true"
        android:icon="@drawable/icon_clock"
        android:title="@string/schedule"/>
    <item
        android:id="@+id/timers"
        android:enabled="true"
        android:icon="@drawable/icon_sand_clock"
        android:title="@string/timers"/>
    <item
        android:id="@+id/stopwatch"
        android:enabled="true"
        android:icon="@drawable/icon_stop_watch"
        android:title="@string/stopwatch"/>
</menu>
      
    
      
val navigationRail = findViewById<NavigationRailView>(R.id.navigation_rail)
navigationRail.selectedItemId = R.id.schedule
navigationRail.setOnItemSelectedListener { item ->
    when (item.itemId) {
        R.id.alarms -> { /* Handle alarms */ true }
        R.id.schedule -> { /* Handle schedule */ true }
        R.id.timers -> { /* Handle timers */ true }
        R.id.stopwatch -> { /* Handle stopwatch */ true }
        else -> false
    }
}
val badge = navigationRail.getOrCreateBadge(R.id.alarms)
badge.isVisible = true
badge.number = 99
navigationRail.expand()
      
    

Adding Badges

  • Show dynamic information like counts or status
  • Use large or small badge variants
      
val navigationRail = findViewById<NavigationRailView>(R.id.navigation_rail)
val badge = navigationRail.getOrCreateBadge(R.id.alarms)
badge.isVisible = true
badge.number = 99
navigationRail.getBadge(R.id.alarms)?.let { badgeDrawable ->
    badgeDrawable.isVisible = false
    badgeDrawable.clearNumber()
}
      
    

Adding Header View

  • Add FAB or logo via app:headerLayout or programmatically
  • Positioned at the top of the rail
      
<com.google.android.material.navigationrail.NavigationRailView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_rail"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    app:headerLayout="@layout/navigation_rail_fab"
    app:menu="@menu/navigation_rail_menu"/>
      
    
      
val navigationRail = findViewById<NavigationRailView>(R.id.navigation_rail)
navigationRail.addHeaderView(findViewById(R.id.fab))
      
    

Expanding Navigation Rail


  • Expanded mode shows all items, including submenus
  • Non-modal, animates with ChangeBounds transition
      
val navigationRail = findViewById<NavigationRailView>(R.id.navigation_rail)
navigationRail.expand()
      
    

Attributes and Usage

Element Attribute Related Method(s) Default Value Usage Description Component Type
Container app:backgroundTint N/A ?attr/colorSurface Sets container background color All
Container app:elevation setElevation 0dp Sets container elevation All
Header app:headerLayout addHeaderView, removeHeaderView, getHeaderView N/A Sets optional header view All
Icon app:itemIconTint setItemIconTintList ?attr/colorOnSecondaryContainer (active), ?attr/colorOnSurfaceVariant (inactive) Sets icon color All
Label app:itemTextColor setItemTextColor ?attr/colorSecondary (active), ?attr/colorOnSurfaceVariant (inactive) Sets label text color All
Active Indicator android:color setItemActiveIndicatorColor ?attr/colorSecondaryContainer Sets active indicator color All
Menu app:menu inflateMenu, getMenu N/A Sets menu resource All

Styles

  • Default style: Widget.Material3.NavigationRailView
  • Default theme attribute: ?attr/navigationRailStyle

Theming Navigation Rails

  • Customize colors and typography
  • Use res/values/styles.xml for theming

Example

      
<style name="Theme.App" parent="Theme.Material3.*">
    <item name="colorPrimary">@color/shrine_pink_100</item>
    <item name="colorSecondary">@color/shrine_pink_200</item>
    <item name="colorSurface">@color/shrine_pink_50</item>
</style>
      
    
      
<style name="Theme.App" parent="Theme.Material3.*">
    <item name="navigationRailStyle">@style/Widget.App.NavigationRailView</item>
</style>
<style name="Widget.App.NavigationRailView" parent="Widget.Material3.NavigationRailView">
    <item name="itemTextColor">@color/shrine_pink_900</item>
    <item name="itemIconTint">@color/shrine_pink_900</item>
    <item name="android:color">@color/shrine_pink_200</item>
</style>
      
    

Material Design Documentation

  • Adheres to Material Design guidelines for Navigation Rails
  • Covers design, behavior, theming specifications
  • Includes structure, accessibility, and expressive updates
  • Refer to Material Design documentation for full details

FAQ

What is a Material 3 Navigation Rail?

  • A vertical navigation bar for tablet/desktop app destinations

How many destinations can it hold?

  • Three to seven when collapsed, unlimited when expanded

When to use a Navigation Rail?

  • Use for primary navigation on larger screens like tablets/desktops

How to make it accessible?

  • Set android:title for TalkBack; adjust labelVisibilityMode

Can I customize appearance?

  • Yes, theme via res/values/styles.xml

How to add the Material 3 library?

  • Include Material Components for Android

Are there updates for the latest standards?

  • Reflects latest Material 3 standards, including expressive updates

Post a Comment

Previous Post Next Post