A bottom app bar displays navigation and key actions at the bottom of mobile screens.
Contents
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.
Android's bottom app bar component APIs provide support for the navigation icon, action items, overflow menu and more for informing the user as to what each action performs. While optional, their use is strongly encouraged.
When using icons for navigation icons, action items and other elements of bottom app bars, you should set a content description on them so that screen readers like TalkBack are able to announce their purpose or action, if any.
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, this can be achieved via the
app:navigationContentDescription
attribute or
setNavigationContentDescription
method.
For action items and items within the overflow menu, the content description needs to be set in the menu:
<menu ...>
...
<item
...
android:contentDescription="@string/content_description_one" />
<item
...
android:contentDescription="@string/content_description_two" />
</menu>
Bottom app bars provide access to a bottom navigation drawer and up to four actions, including the floating action button.
API and source code:
CoordinatorLayout
BottomAppBar
FloatingActionButton
The following example shows a bottom app bar with a navigation icon, an action icon, a cradled FAB, and an overflow menu.
In the layout:
<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"
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
app:navigationIcon="@drawable/ic_menu_24dp"
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
:
<menu
...>
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_24dp"
android:title="@string/search"
android:contentDescription="@string/content_description_search"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/more"
android:title="@string/more"
android:contentDescription="@string/content_description_more"
app:showAsAction="never"
/>
</menu>
In menu/navigation icon drawables:
<vector
...
android:tint="?attr/colorControlNormal">
...
</vector>
In code:
bottomAppBar.setNavigationOnClickListener {
// Handle navigation icon press
}
bottomAppBar.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.search -> {
// Handle search icon press
true
}
R.id.more -> {
// Handle more item (inside overflow menu) press
true
}
else -> false
}
}
The following example shows the bottom app bar hiding upon scrolling the scrollable content down, and appearring upon scrolling up.
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
...
<com.google.android.material.bottomappbar.BottomAppBar
...
app:hideOnScroll="true"
/>
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
A bottom app bar has a container and an optional navigation icon, anchored floating action button (FAB), action item(s) and an overflow menu.
- Container
- Navigation icon (optional)
- Floating action button (FAB) (optional)
- Action item(s) (optional)
- Overflow menu (optional)
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Color | app:backgroundTint |
setBackgroundTint getBackgroundTint |
?attr/colorSurface |
Elevation | app:elevation |
setElevation |
8dp |
Height | android:minHeight |
setMinimumHeight getMinimumHeight |
56dp (default) and 64dp (w600dp) |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Icon | app:navigationIcon |
setNavigationIcon getNavigationIcon |
null |
Color | N/A | N/A | ?attr/colorControlNormal (as Drawable tint) |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Alignment mode | app:fabAlignmentMode |
setFabAlignmentMode getFabAlignmentMode |
center |
Animation mode | app:fabAnimationMode |
setFabAnimationMode getFabAnimationMode |
scale |
Cradle margin | app:fabCradleMargin |
setFabCradleMargin getFabCradleMargin |
5dp |
Cradle rounded corner radius | app:fabCradleRoundedCornerRadius |
setFabCradleRoundedCornerRadius getFabCradleRoundedCornerRadius |
8dp |
Cradle vertical offset | app:fabCradleVerticalOffset |
setCradleVerticalOffset getCradleVerticalOffset |
0dp |
See the FAB documentation for more attributes.
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Menu | app:menu |
replaceMenu getMenu |
null |
Icon color | N/A | N/A | ?attr/colorControlNormal (as Drawable tint) |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Icon | android: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) |
Theme | app:popupTheme |
setPopupTheme getPopupTheme |
@style/ThemeOverlay.MaterialComponents.* |
Item typography | textAppearanceSmallPopupMenu and textAppearanceLargePopupMenu in app:popupTheme or app theme |
N/A | ?attr/textAppearanceSubtitle1 |
Element | Style |
---|---|
Default style | Widget.MaterialComponents.BottomAppBar |
Primary background color style | Widget.MaterialComponents.BottomAppBar.Colored |
Primary (light theme) or surface (dark theme) background color style |
Widget.MaterialComponents.BottomAppBar.PrimarySurface |
Default style theme attribute: bottomAppBarStyle
See the full list of styles and attrs.
Bottom app bars support Material Theming and can be customized in terms of color, typography and shape.
API and source code:
CoordinatorLayout
BottomAppBar
FloatingActionButton
BottomAppBarCutCornersTopEdge
:
The following example shows a bottom app bar with Material Theming.
Using theme attributes in res/values/styles.xml
(themes all bottom app bars
and FABs and affects other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="colorSecondary">@color/shrine_pink_50</item>
<item name="colorOnSecondary">@color/shrine_pink_900</item>
<item name="textAppearanceSubtitle1">@style/TextAppearance.App.Subtitle1</item>
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
</style>
<style name="TextAppearance.App.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
<item name="fontFamily">@font/rubik</item>
<item name="android:fontFamily">@font/rubik</item>
</style>
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerFamily">cut</item>
<item name="cornerSize">4dp</item>
</style>
or using default style theme attributes, styles and theme overlays (themes all bottom app bars and FABs but does not affect other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="bottomAppBarStyle">@style/Widget.App.BottomAppBar</item>
<item name="floatingActionButtonStyle">@style/Widget.App.FloatingActionButton</item>
</style>
<style name="Widget.App.BottomAppBar" parent="Widget.MaterialComponents.BottomAppBar.Colored">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.BottomAppBar</item>
</style>
<style name="Widget.App.FloatingActionButton" parent="Widget.MaterialComponents.FloatingActionButton">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.FloatingActionButton</item>
</style>
<style name="ThemeOverlay.App.BottomAppBar" parent="">
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="textAppearanceSubtitle1">@style/TextAppearance.App.Subtitle1</item>
</style>
<style name="ThemeOverlay.App.FloatingActionButton" parent="">
<item name="colorSecondary">@color/shrine_pink_50</item>
<item name="colorOnSecondary">@color/shrine_pink_900</item>
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
</style>
or using the styles in the layout (affects only this bottom app bar and FAB):
<com.google.android.material.bottomappbar.BottomAppBar
...
style="@style/Widget.App.BottomAppBar"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
...
style="@style/Widget.App.FloatingActionButton"
/>
In code:
val topEdge = BottomAppBarCutCornersTopEdge(
bottomAppBar.fabCradleMargin,
bottomAppBar.fabCradleRoundedCornerRadius,
bottomAppBar.cradleVerticalOffset
)
val background = bottomAppBar.background as MaterialShapeDrawable
background.shapeAppearanceModel = background.shapeAppearanceModel.toBuilder().setTopEdge(topEdge).build()
Note: Using BottomAppBarCutCornersTopEdge
is not necessary with rounded
shapeAppearance corners.