|
| 1 | +<!--docs: |
| 2 | +title: "Docked Toolbar" |
| 3 | +layout: detail |
| 4 | +section: components |
| 5 | +excerpt: "Docked toolbars show actions related to the current page" |
| 6 | +iconId: docked_toolbar |
| 7 | +path: /catalog/docked-toolbar/ |
| 8 | +--> |
| 9 | + |
| 10 | +# Docked Toolbar |
| 11 | + |
| 12 | +Docked Toolbar provides a way to show actions related to the current page. |
| 13 | +Docked Toolbar is one variant of Toolbars. Toolbars can also be undocked, ie. [Floating Toolbars](FloatingToolbar.md). |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | +**Contents** |
| 18 | + |
| 19 | +* [Design and API Documentation](#design-and-api-documentation) |
| 20 | +* [Using Docked Toolbar](#using-docked-toolbar) |
| 21 | +* [Theming](#theming-a-docked-toolbar) |
| 22 | + |
| 23 | +## Design and API Documentation |
| 24 | + |
| 25 | +* Google Material3 Spec in progress |
| 26 | +* API Reference in progress |
| 27 | + |
| 28 | +## Using Docked Toolbar |
| 29 | + |
| 30 | +Before you can use the Docked Toolbar, you need to add a dependency to |
| 31 | +the Material Components for Android library. For more information, go to the |
| 32 | +[Getting started](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md) |
| 33 | +page. |
| 34 | + |
| 35 | +Here's what a typical layout would look like: |
| 36 | + |
| 37 | +```xml |
| 38 | +<androidx.coordinatorlayout.widget.CoordinatorLayout |
| 39 | + xmlns:android="http://schemas.android.com/apk/res/android" |
| 40 | + xmlns:app="http://schemas.android.com/apk/res-auto" |
| 41 | + android:layout_width="match_parent" |
| 42 | + android:layout_height="match_parent"> |
| 43 | + |
| 44 | + <!-- sample screen content --> |
| 45 | + <androidx.core.widget.NestedScrollView |
| 46 | + android:layout_width="match_parent" |
| 47 | + android:layout_height="match_parent"> |
| 48 | + <LinearLayout |
| 49 | + android:layout_width="match_parent" |
| 50 | + android:layout_height="wrap_content"> |
| 51 | + |
| 52 | + <TextView |
| 53 | + android:layout_width="wrap_content" |
| 54 | + android:layout_height="wrap_content" |
| 55 | + android:text="@string/content" /> |
| 56 | + </LinearLayout> |
| 57 | + </androidx.core.widget.NestedScrollView> |
| 58 | + |
| 59 | + <com.google.android.material.dockedtoolbar.DockedToolbar |
| 60 | + android:id="@+id/docked_toolbar" |
| 61 | + android:layout_width="match_parent" |
| 62 | + android:layout_height="wrap_content" |
| 63 | + android:layout_gravity="bottom" |
| 64 | + app:layout_behavior="com.google.android.material.behavior.HideViewOnScrollBehavior"> |
| 65 | + |
| 66 | + <!-- docked toolbar sample content --> |
| 67 | + <LinearLayout |
| 68 | + android:id="@+id/docked_toolbar_child" |
| 69 | + android:layout_width="match_parent" |
| 70 | + android:layout_height="wrap_content" |
| 71 | + android:layout_gravity="center" |
| 72 | + android:orientation="horizontal"> |
| 73 | + <FrameLayout |
| 74 | + android:layout_width="0dp" |
| 75 | + android:layout_height="wrap_content" |
| 76 | + android:layout_weight="1"> |
| 77 | + <Button |
| 78 | + android:id="@+id/docked_toolbar_back_button" |
| 79 | + android:layout_width="wrap_content" |
| 80 | + android:layout_height="wrap_content" |
| 81 | + android:layout_gravity="center" |
| 82 | + style="?attr/materialIconButtonStyle" |
| 83 | + android:contentDescription="@string/docked_toolbar_back_button_description" |
| 84 | + app:icon="@drawable/ic_arrow_back_24px" /> |
| 85 | + </FrameLayout> |
| 86 | + |
| 87 | + <FrameLayout |
| 88 | + android:layout_width="0dp" |
| 89 | + android:layout_height="wrap_content" |
| 90 | + android:layout_weight="1"> |
| 91 | + <Button |
| 92 | + android:id="@+id/docked_toolbar_add_button" |
| 93 | + android:layout_width="wrap_content" |
| 94 | + android:layout_height="wrap_content" |
| 95 | + android:layout_gravity="center" |
| 96 | + style="?attr/materialIconButtonStyle" |
| 97 | + android:contentDescription="@string/docked_toolbar_add_button_description" |
| 98 | + app:icon="@drawable/ic_add_24px" /> |
| 99 | + </FrameLayout> |
| 100 | + |
| 101 | + <FrameLayout |
| 102 | + android:layout_width="0dp" |
| 103 | + android:layout_height="wrap_content" |
| 104 | + android:layout_weight="1"> |
| 105 | + <Button |
| 106 | + android:id="@+id/docked_toolbar_forward_button" |
| 107 | + android:layout_width="wrap_content" |
| 108 | + android:layout_height="wrap_content" |
| 109 | + android:layout_gravity="center" |
| 110 | + style="?attr/materialIconButtonStyle" |
| 111 | + android:contentDescription="@string/docked_toolbar_forward_button_description" |
| 112 | + app:icon="@drawable/ic_arrow_forward_24px" /> |
| 113 | + </FrameLayout> |
| 114 | + </LinearLayout> |
| 115 | + |
| 116 | + </com.google.android.material.dockedtoolbar.DockedToolbarLayout> |
| 117 | +</androidx.coordinatorlayout.widget.CoordinatorLayout> |
| 118 | +``` |
| 119 | + |
| 120 | +A Docked Toolbar is a `FrameLayout` that provides additional styling. |
| 121 | +You may add children to it as you would to a `FrameLayout`. |
| 122 | + |
| 123 | +Docked toolbars can optionally hide on scroll off the bottom if inside a |
| 124 | +`CoordinatorLayout` by setting the following `CoordinatorLayout.Behavior` |
| 125 | +through the `app:layout_behavior` attribute: |
| 126 | + |
| 127 | +```xml |
| 128 | +<com.google.android.material.dockedtoolbar.DockedToolbarLayout |
| 129 | + android:id="@+id/docked_toolbar" |
| 130 | + android:layout_width="match_parent" |
| 131 | + android:layout_height="wrap_content" |
| 132 | + android:layout_gravity="bottom" |
| 133 | + app:layout_behavior="com.google.android.material.behavior.HideViewOnScrollBehavior"> |
| 134 | + ... |
| 135 | +</com.google.android.material.dockedtoolbar.DockedToolbarLayout> |
| 136 | +``` |
| 137 | + |
| 138 | +[Top App Bars](TopAppBar.md) and [Bottom App Bars](BottomAppBar.md) are also |
| 139 | +implementations of a docked toolbar which offer more in terms of functionality, |
| 140 | +but are less flexible than the `DockedToolbarLayout` implementation. |
| 141 | + |
| 142 | +API and source code: |
| 143 | + |
| 144 | +* `DockedToolbar` |
| 145 | + * [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/dockedtoolbar/DockedToolbarLayout.java) |
| 146 | + |
| 147 | +### Making Docked Toolbar accessible |
| 148 | + |
| 149 | +You should set a `contentDescription` on all the actions in the Docked Toolbar |
| 150 | +so that screen readers like TalkBack can properly announce what each action |
| 151 | +represents. |
| 152 | + |
| 153 | +You can also control the ordering of the Talkback focus through the |
| 154 | +`accessibilityTraversalBefore` and `accessibilityTraversalAfter` flags. |
| 155 | + |
| 156 | +For example, if you want the Docked Toolbar to gain Talkback focus first, you |
| 157 | +can set these accessibility flags like below: |
| 158 | + |
| 159 | +```xml |
| 160 | + <!-- sample screen content --> |
| 161 | + <androidx.core.widget.NestedScrollView |
| 162 | + android:layout_width="match_parent" |
| 163 | + android:layout_height="match_parent"> |
| 164 | + <LinearLayout |
| 165 | + android:layout_width="match_parent" |
| 166 | + android:layout_height="wrap_content"> |
| 167 | + |
| 168 | + <TextView |
| 169 | + android:id="@+id/content" |
| 170 | + android:layout_width="wrap_content" |
| 171 | + android:layout_height="wrap_content" |
| 172 | + android:text="@string/content" |
| 173 | + android:accessibilityTraversalAfter="@id/docked_toolbar" /> |
| 174 | + </LinearLayout> |
| 175 | + </androidx.core.widget.NestedScrollView> |
| 176 | + |
| 177 | + <com.google.android.material.dockedbar.DockedToolbarLayout |
| 178 | + android:id="@+id/docked_toolbar" |
| 179 | + android:layout_width="wrap_content" |
| 180 | + android:layout_height="wrap_content" |
| 181 | + android:accessibilityTraversalBefore="@id/content"> |
| 182 | + ... |
| 183 | + </com.google.android.material.dockedtoolbar.DockedToolbarLayout> |
| 184 | +``` |
| 185 | + |
| 186 | +### Anatomy and key properties |
| 187 | + |
| 188 | +The following is an anatomy diagram for the docked toolbar: |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | +1. Container |
| 193 | +2. Content |
| 194 | + |
| 195 | +#### Container attributes |
| 196 | + |
| 197 | +**Element** | **Attribute** | **Related methods** | **Default value** |
| 198 | +----------------------- | ------------------------------------ | ------------------- | ----------------- |
| 199 | +**Color** | `app:backgroundTint` | N/A | `?attr/colorSurfaceContainer` |
| 200 | +**Shape** | `app:shapeAppearance` | N/A | `0% rounded` |
| 201 | +**Top inset padding** | `app:paddingTopSystemWindowInsets` | N/A | `unset` |
| 202 | +**Bottom inset padding**| `app:paddingBottomSystemWindowInsets` | N/A | `unset` |
| 203 | + |
| 204 | +**Note:** `DockedToolbarLayout` automatically adds top or bottom inset based on |
| 205 | +its gravity inside a `CoordinatorLayout`, if `app:paddingTopSystemWindowInsets` |
| 206 | +or `app:paddingBottomSystemWindowInsets` is not set. If not using a Docked |
| 207 | +Toolbar inside a `CoordinatorLayout`, set these attributes explicitly to add |
| 208 | +inset padding. |
| 209 | + |
| 210 | +#### Styles |
| 211 | + |
| 212 | +**Element** | **Style** |
| 213 | +------------------ | ------------------------------------------ |
| 214 | +**Default style** | `Widget.Material3.DockedToolbar` |
| 215 | + |
| 216 | +Default style theme attribute: `?attr/dockedToolbarStyle` |
| 217 | + |
| 218 | +See the full list of |
| 219 | +[styles](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/dockedtoolbar/res/values/styles.xml) and |
| 220 | +[docked toolbar attributes](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/dockedtoolbar/res/values/attrs.xml) |
| 221 | + |
| 222 | +## Theming a Docked Toolbar |
| 223 | + |
| 224 | +Docked Toolbar supports [Material Theming](https://m3.material.io/foundations/customization), |
| 225 | +which can customize color and typography. |
| 226 | + |
| 227 | +### Docked Toolbar theming example |
| 228 | + |
| 229 | +The following example shows a Docked Toolbar with Material Theming. |
| 230 | + |
| 231 | + |
| 232 | + |
| 233 | +#### Implementing docked toolbar theming |
| 234 | + |
| 235 | +Use theme attributes and a style in `res/values/styles.xml` which apply to all |
| 236 | +docked toolbars and affect other components: |
| 237 | + |
| 238 | +```xml |
| 239 | +<style name="Theme.App" parent="Theme.Material3.*"> |
| 240 | + ... |
| 241 | + <item name="colorPrimary">@color/shrine_theme_light_primary</item> |
| 242 | + <item name="colorOnPrimary">@color/shrine_theme_light_onPrimary</item> |
| 243 | + <item name="colorPrimaryContainer">@color/shrine_theme_light_primaryContainer</item> |
| 244 | + <item name="colorOnPrimaryContainer">@color/shrine_theme_light_onPrimaryContainer</item> |
| 245 | + <item name="colorSecondaryContainer">@color/shrine_theme_light_secondaryContainer</item> |
| 246 | + <item name="colorOnSecondaryContainer">@color/shrine_theme_light_onSecondaryContainer</item> |
| 247 | + <item name="colorTertiaryContainer">@color/shrine_theme_light_tertiaryContainer</item> |
| 248 | + <item name="colorOnTertiaryContainer">@color/shrine_theme_light_onTertiaryContainer</item> |
| 249 | + <item name="colorError">@color/shrine_theme_light_error</item> |
| 250 | + <item name="colorErrorContainer">@color/shrine_theme_light_errorContainer</item> |
| 251 | + <item name="colorOnError">@color/shrine_theme_light_onError</item> |
| 252 | + <item name="colorOnErrorContainer">@color/shrine_theme_light_onErrorContainer</item> |
| 253 | + <item name="colorSurface">@color/shrine_theme_light_surface</item> |
| 254 | + <item name="colorOnSurface">@color/shrine_theme_light_onSurface</item> |
| 255 | + <item name="colorOnSurfaceVariant">@color/shrine_theme_light_onSurfaceVariant</item> |
| 256 | +</style> |
| 257 | +``` |
| 258 | + |
| 259 | +Use a default style theme attribute, styles, and a theme overlay, which apply to |
| 260 | +all docked toolbars but do not affect other components: |
| 261 | + |
| 262 | +```xml |
| 263 | +<style name="Theme.App" parent="Theme.Material3.*"> |
| 264 | + ... |
| 265 | + <item name="dockedToolbarStyle">@style/Widget.App.DockedToolbar</item> |
| 266 | +</style> |
| 267 | + |
| 268 | +<style name="Widget.App.DockedToolbar" parent="Widget.Material3.DockedToolbar"> |
| 269 | + <item name="materialThemeOverlay">@style/ThemeOverlay.App.DockedToolbar</item> |
| 270 | +</style> |
| 271 | + |
| 272 | +<style name="ThemeOverlay.App.DockedToolbar" parent=""> |
| 273 | + <item name="colorPrimary">@color/shrine_theme_light_primary</item> |
| 274 | + <item name="colorOnPrimary">@color/shrine_theme_light_onPrimary</item> |
| 275 | + <item name="colorPrimaryContainer">@color/shrine_theme_light_primaryContainer</item> |
| 276 | + <item name="colorOnPrimaryContainer">@color/shrine_theme_light_onPrimaryContainer</item> |
| 277 | + <item name="colorSecondaryContainer">@color/shrine_theme_light_secondaryContainer</item> |
| 278 | + <item name="colorOnSecondaryContainer">@color/shrine_theme_light_onSecondaryContainer</item> |
| 279 | + <item name="colorTertiaryContainer">@color/shrine_theme_light_tertiaryContainer</item> |
| 280 | + <item name="colorOnTertiaryContainer">@color/shrine_theme_light_onTertiaryContainer</item> |
| 281 | + <item name="colorError">@color/shrine_theme_light_error</item> |
| 282 | + <item name="colorErrorContainer">@color/shrine_theme_light_errorContainer</item> |
| 283 | + <item name="colorOnError">@color/shrine_theme_light_onError</item> |
| 284 | + <item name="colorOnErrorContainer">@color/shrine_theme_light_onErrorContainer</item> |
| 285 | + <item name="colorSurface">@color/shrine_theme_light_surface</item> |
| 286 | + <item name="colorOnSurface">@color/shrine_theme_light_onSurface</item> |
| 287 | + <item name="colorOnSurfaceVariant">@color/shrine_theme_light_onSurfaceVariant</item> |
| 288 | +</style> |
| 289 | +``` |
| 290 | + |
| 291 | +Or use the style in the layout, which affects only this specific docked toolbar: |
| 292 | + |
| 293 | +```xml |
| 294 | +<com.google.android.material.dockedtoolbar.DockedToolbarLayout |
| 295 | + ... |
| 296 | + style="@style/Widget.App.DockedToolbar" |
| 297 | +/> |
| 298 | +``` |
0 commit comments