Back to Material Components Android

Bottom app bars

docs/components/BottomAppBar.md

1.13.017.1 KB
Original Source
<!--docs: title: "Bottom app bars" layout: detail section: components excerpt: "Android bottom app bars." iconId: bottom_app_bar path: /catalog/bottom-app-bars/ -->

Bottom app bars

Note: The bottom app bar is being deprecated and should be replaced with the docked toolbar, which functions similarly, but is shorter and has more flexibility.

A bottom app bar displays navigation and key actions at the bottom of mobile screens.

Note: Images use various dynamic color schemes.

Bottom app bars provide access to up to four actions, including the floating action button (FAB).

Design & API documentation

Anatomy

  1. Container
  2. Floating action button (FAB) (optional)
  3. Action item(s) (optional)
  4. Navigation icon (optional)
  5. Overflow menu (optional)

Note: This doc reflects the Bottom App Bar after the changes in 1.7 to reflect the current M3 style. Use Widget.Material3.BottomAppBar.Legacy to revert back to the previous style.

M3 Expressive update

Before you can use Material3Expressive component styles, follow the Material3Expressive themes setup instructions.

The bottom app bar is being deprecated and should be replaced with the docked toolbar, which functions similarly, but is shorter and has more flexibility.

Types and naming:

  • Added docked toolbar to replace bottom app bar

    • Size: Shorter height
    • Color: Standard or vibrant
    • Flexibility: More layout and element options
  • Bottom app bar is still available, but not recommended

Key properties

Container attributes

ElementAttributeRelated method(s)Default value
Colorapp:backgroundTintsetBackgroundTint
getBackgroundTint?attr/colorSurfaceContainer
Elevationapp:elevationsetElevation3dp
Heightandroid:minHeightsetMinimumHeight
getMinimumHeight80dp
Shadowsapp:addElevationShadowN/Afalse
ElementAttributeRelated method(s)Default value
Iconapp:navigationIconsetNavigationIcon
getNavigationIconnull
Colorapp:navigationIconTintsetNavigationIconTint?attr/colorOnSurfaceVariant (as Drawable tint)

FAB attributes

ElementAttributeRelated method(s)Default value
Alignment modeapp:fabAlignmentModesetFabAlignmentMode
getFabAlignmentModeend
Animation modeapp:fabAnimationModesetFabAnimationMode
getFabAnimationModeslide
Anchor modeapp:fabAnchorModesetFabAnchorMode
getFabAnchorModeembed
Cradle marginapp:fabCradleMarginsetFabCradleMargin
getFabCradleMargin6dp
Cradle rounded corner radiusapp:fabCradleRoundedCornerRadiussetFabCradleRoundedCornerRadius
getFabCradleRoundedCornerRadius4dp
Cradle vertical offsetapp:fabCradleVerticalOffsetsetCradleVerticalOffset
getCradleVerticalOffset12dp
End marginapp:fabAlignmentModeEndMarginsetFabAlignmentModeEndMargin
getFabAlignmentModeEndMargin16dp
Embedded elevationapp:removeEmbeddedFabElevationN/Atrue

See the FAB documentation for more attributes.

Action item(s) attributes

ElementAttributeRelated method(s)Default value
Menuapp:menureplaceMenu
getMenunull
Icon colorN/AN/A?attr/colorControlNormal (as Drawable tint)
Alignment modeapp:menuAlignmentModesetMenuAlignmentMode
getMenuAlignmentModestart

Overflow menu attributes

ElementAttributeRelated method(s)Default value
Iconandroid:src and app:srcCompat in actionOverflowButtonStyle (in app theme)setOverflowIcon
getOverflowIcon@drawable/abc_ic_menu_overflow_material (before API 23) or @drawable/ic_menu_moreoverflow_material (after API 23)
Themeapp:popupThemesetPopupTheme
getPopupTheme@style/ThemeOverlay.Material3.*
Item typographytextAppearanceSmallPopupMenu and textAppearanceLargePopupMenu in app:popupTheme or app themeN/A?attr/textAppearanceTitleMedium

Styles

ElementStyleTheme attribute
Default styleWidget.Material3.BottomAppBarbottomAppBarStyle

See the full list of styles and attrs.

Code implementation

Before you can use Material bottom app bars, you need to add a dependency to the Material Components for Android library. For more information, go to the Getting started page.

Bottom app bar examples

The following example shows a bottom app bar with a navigation icon, 3 action icons, and an embedded FAB.

In the layout:

xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Note: A RecyclerView can also be used -->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="100dp"
        android:clipToPadding="false">

        <!-- Scrollable content -->

    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:navigationIcon="@drawable/ic_drawer_menu_24px"
        app:menu="@menu/bottom_app_bar"
        />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/ic_add_24dp"
        app:layout_anchor="@id/bottomAppBar"
        />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

In menu/bottom_app_bar.xml:

xml
<menu
      ...>
    <item
      android:id="@+id/accelerator"
      android:icon="@drawable/ic_accelerator_24px"
      android:title="@string/accelerator"
      android:contentDescription="@string/content_description_accelerator"
      app:showAsAction="ifRoom"/>

    <item
      android:id="@+id/rotation"
      android:icon="@drawable/ic_3d_rotation_24px"
      android:title="@string/rotation"
      android:contentDescription="@string/content_description_rotation"
      app:showAsAction="ifRoom"/>

    <item
      android:id="@+id/dashboard"
      android:icon="@drawable/ic_dashboard_24px"
      android:title="@string/dashboard"
      android:contentDescription="@string/content_description_dashboard"
      app:showAsAction="ifRoom"/>

</menu>

In menu/navigation icon drawables:

xml
<vector
    ...
    android:tint="?attr/colorControlNormal">
    ...
</vector>

In code:

kt
bottomAppBar.setNavigationOnClickListener {
    // Handle navigation icon press
}

bottomAppBar.setOnMenuItemClickListener { menuItem ->
    when (menuItem.itemId) {
        R.id.accelerator -> {
            // Handle accelerator icon press
            true
        }
        R.id.rotation -> {
            // Handle rotation icon press
            true
        }
        R.id.dashboard -> {
            // Handle dashboard icon press
            true
        }
        else -> false
    }
}

Making bottom app bars accessible

Android's bottom app bar component APIs provide support for the navigation icon, action items, overflow menu and more to tell the user what each action performs. While optional, their use is strongly encouraged.

Content descriptions

When using navigation icons, action items and other elements of bottom app bars, you should set a content description for them so that screen readers like TalkBack are able to announce their purpose or action.

For an overall content description of the bottom app bar, set an android:contentDescription or use the setContentDescription method on the BottomAppBar.

For the navigation icon, use the app:navigationContentDescription attribute or setNavigationContentDescription method.

For action items and items within the overflow menu, set the content description in the menu:

xml
<menu ...>
    ...
    <item
          ...
          android:contentDescription="@string/content_description_one" />
    <item
          ...
          android:contentDescription="@string/content_description_two" />
</menu>

Talkback

Bottom app bar can optionally hide on scroll with the app:hideOnScroll attribute. When this attribute is set to true, scrolling will hide the bottom app bar and prevent it from being seen by any screen readers which may be confusing for users. To prevent this, the hide behavior is automatically disabled when Talkback is enabled. Although discouraged for accessibility, you can optionally force the hide behavior by calling bottomAppBar.disableHideOnTouchExploration(false).

Depending on your layout, disabling the hide behavior may potentially cause content to be obscured behind the bar. Make sure to add the appropriate bottom padding of the height of the bottom app bar to the content. See below for an example:

val am = context.getSystemService(AccessibilityManager::class.java)
if (am != null && am.isTouchExplorationEnabled) {
    bar.setHideOnScroll(false)
    bar.post {
        content.setPadding(
            content.paddingLeft,
            content.paddingTop,
            content.paddingRight,
            content.paddingBottom + bar.measuredHeight
        )
    }
}

Applying scrolling behavior to bottom app bars

The following example shows the bottom app bar hiding when scrolling the scrollable content down, and appearing when scrolling up.

xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...>

    ...

    <com.google.android.material.bottomappbar.BottomAppBar
        ...
        app:hideOnScroll="true"
        />

    ...

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Customizing bottom app bars

Theming bottom app bars

Bottom app bars support the customization of color, typography, and shape.

Bottom app bar theming example

API and source code:

The following example shows a bottom app bar with Material theming.

Implementing bottom app bar theming

Use theme attributes in res/values/styles.xml, which applies the theme to all bottom app bars and FABs and affects other components:

xml
<style name="Theme.App" parent="Theme.Material3.*">
    ...
    <item name="colorSurfaceContainer">@color/shrine_pink_100</item>
    <item name="colorOnSurface">@color/shrine_pink_900</item>
    <item name="colorPrimaryContainer">@color/shrine_pink_50</item>
    <item name="colorOnPrimaryContainer">@color/shrine_pink_900</item>
    <item name="textAppearanceTitleMedium">@style/TextAppearance.App.Medium</item>
    <item name="shapeAppearanceCornerLarge">@style/ShapeAppearance.App.Corner.Large</item>
</style>

<style name="TextAppearance.App.Medium" parent="TextAppearance.Material3.TitleMedium">
    <item name="fontFamily">@font/rubik</item>
    <item name="android:fontFamily">@font/rubik</item>
</style>

<style name="ShapeAppearance.App.Corner.Large" parent="ShapeAppearance.Material3.Corner.Large">
    <item name="cornerFamily">cut</item>
    <item name="cornerSize">50%</item>
</style>

Use default style theme attributes, styles and theme overlays, which applies the theme to all bottom app bars and FABs but does not affect other components:

xml
<style name="Theme.App" parent="Theme.Material3.*">
    ...
    <item name="bottomAppBarStyle">@style/Widget.App.BottomAppBar</item>
    <item name="floatingActionButtonStyle">@style/Widget.App.FloatingActionButton</item>
</style>

<style name="Widget.App.BottomAppBar" parent="Widget.Material3.BottomAppBar">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.BottomAppBar</item>
</style>

<style name="Widget.App.FloatingActionButton" parent="Widget.Material3.FloatingActionButton.Primary">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.FloatingActionButton</item>
</style>

<style name="ThemeOverlay.App.BottomAppBar" parent="ThemeOverlay.Material3.BottomAppBar">
    <item name="colorSurfaceContainer">@color/shrine_pink_100</item>
    <item name="colorOnSurface">@color/shrine_pink_900</item>
    <item name="textAppearanceTitleMedium">@style/TextAppearance.App.TitleMedium</item>
</style>

<style name="ThemeOverlay.App.FloatingActionButton" parent="ThemeOverlay.Material3.FloatingActionButton.Primary">
    <item name="colorPrimaryContainer">@color/shrine_pink_50</item>
    <item name="colorOnPrimaryContainer">@color/shrine_pink_900</item>
    <item name="shapeAppearanceCornerLarge">@style/ShapeAppearance.App.Corner.Large</item>
</style>

Use the styles in the layout, which affects only this bottom app bar and FAB:

xml
<com.google.android.material.bottomappbar.BottomAppBar
    ...
    style="@style/Widget.App.BottomAppBar"
    />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    ...
    style="@style/Widget.App.FloatingActionButton"
    />