diff --git a/catalog/java/io/material/catalog/bottomappbar/BottomAppBarMainDemoFragment.java b/catalog/java/io/material/catalog/bottomappbar/BottomAppBarMainDemoFragment.java
index 9f83f6ee67a..e0568c6a8f6 100644
--- a/catalog/java/io/material/catalog/bottomappbar/BottomAppBarMainDemoFragment.java
+++ b/catalog/java/io/material/catalog/bottomappbar/BottomAppBarMainDemoFragment.java
@@ -190,6 +190,21 @@ private void setUpDemoControls(@NonNull View view) {
cradleButton.setOnClickListener(
v -> bar.setFabAnchorMode(BottomAppBar.FAB_ANCHOR_MODE_CRADLE));
+ // Set up menu alignment toggle buttons.
+ MaterialButton menuAlignmentAutoButton = view.findViewById(R.id.menu_alignment_auto);
+ MaterialButton menuAlignmentStartButton = view.findViewById(R.id.menu_alignment_start);
+
+ if (bar.getMenuAlignmentMode() == BottomAppBar.MENU_ALIGNMENT_MODE_AUTO) {
+ menuAlignmentAutoButton.setChecked(true);
+ } else {
+ menuAlignmentStartButton.setChecked(true);
+ }
+
+ menuAlignmentAutoButton.setOnClickListener(
+ v -> bar.setMenuAlignmentMode(BottomAppBar.MENU_ALIGNMENT_MODE_AUTO));
+ menuAlignmentStartButton.setOnClickListener(
+ v -> bar.setMenuAlignmentMode(BottomAppBar.MENU_ALIGNMENT_MODE_START));
+
// Set up hide on scroll switch.
MaterialSwitch barScrollSwitch = view.findViewById(R.id.bar_scroll_switch);
barScrollSwitch.setChecked(bar.getHideOnScroll());
diff --git a/catalog/java/io/material/catalog/bottomappbar/res/layout/cat_bottomappbar_content.xml b/catalog/java/io/material/catalog/bottomappbar/res/layout/cat_bottomappbar_content.xml
index 79542c4bccc..022980fe538 100644
--- a/catalog/java/io/material/catalog/bottomappbar/res/layout/cat_bottomappbar_content.xml
+++ b/catalog/java/io/material/catalog/bottomappbar/res/layout/cat_bottomappbar_content.xml
@@ -131,6 +131,29 @@
android:text="@string/cat_bottomappbar_button_cradle" />
+
+
+
+
+
+
Fab Animation Mode
Fab Visibility Mode
Fab Anchor Mode
+ Menu Alignment Mode
+
Embed
Cradle
+ Auto
+ Start
diff --git a/docs/components/BottomAppBar.md b/docs/components/BottomAppBar.md
index c6e8218c870..f5ff8ac82f8 100644
--- a/docs/components/BottomAppBar.md
+++ b/docs/components/BottomAppBar.md
@@ -245,10 +245,11 @@ for more attributes.
#### Action item(s) 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
+------------------ | ----------------------- | -------------------------------------------------- | -------------
+**Menu** | `app:menu` | `replaceMenu`
`getMenu` | `null`
+**Icon color** | N/A | N/A | `?attr/colorControlNormal` (as `Drawable` tint)
+**Alignment mode** | `app:menuAlignmentMode` | `setMenuAlignmentMode`
`getMenuAlignmentMode` | `auto`
### Overflow menu attributes
diff --git a/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java b/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java
index 46abfe84ae5..d30ac4af75a 100644
--- a/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java
+++ b/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java
@@ -164,6 +164,21 @@ public class BottomAppBar extends Toolbar implements AttachedBehavior {
@Retention(RetentionPolicy.SOURCE)
public @interface FabAnimationMode {}
+ /** The menu items are aligned automatically to avoid the FAB. */
+ public static final int MENU_ALIGNMENT_MODE_AUTO = 0;
+ /** The menu items are aligned to the start. */
+ public static final int MENU_ALIGNMENT_MODE_START = 1;
+
+ /**
+ * The menuAlignmentMode determines the alignment of the menu items in the BottomAppBar.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @IntDef({MENU_ALIGNMENT_MODE_AUTO, MENU_ALIGNMENT_MODE_START})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MenuAlignmentMode {}
+
@Nullable private Integer navigationIconTint;
private final int fabOffsetEndMode;
private final MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable();
@@ -173,6 +188,7 @@ public class BottomAppBar extends Toolbar implements AttachedBehavior {
@FabAlignmentMode private int fabAlignmentMode;
@FabAnimationMode private int fabAnimationMode;
@FabAnchorMode private int fabAnchorMode;
+ @MenuAlignmentMode private int menuAlignmentMode;
private boolean hideOnScroll;
private final boolean paddingBottomSystemWindowInsets;
private final boolean paddingLeftSystemWindowInsets;
@@ -302,6 +318,8 @@ public BottomAppBar(@NonNull Context context, @Nullable AttributeSet attrs, int
fabAnimationMode =
a.getInt(R.styleable.BottomAppBar_fabAnimationMode, FAB_ANIMATION_MODE_SCALE);
fabAnchorMode = a.getInt(R.styleable.BottomAppBar_fabAnchorMode, FAB_ANCHOR_MODE_CRADLE);
+ menuAlignmentMode =
+ a.getInt(R.styleable.BottomAppBar_menuAlignmentMode, MENU_ALIGNMENT_MODE_AUTO);
hideOnScroll = a.getBoolean(R.styleable.BottomAppBar_hideOnScroll, false);
// Reading out if we are handling bottom padding, so we can apply it to the FAB.
paddingBottomSystemWindowInsets =
@@ -484,6 +502,32 @@ public void setFabAnimationMode(@FabAnimationMode int fabAnimationMode) {
this.fabAnimationMode = fabAnimationMode;
}
+ /**
+ * Sets the current {@code menuAlignmentMode}. Determines where the menu items in the BottomAppBar
+ * will be aligned.
+ *
+ * @param menuAlignmentMode the desired menuAlignmentMode, either {@link
+ * #MENU_ALIGNMENT_MODE_AUTO} or {@link #MENU_ALIGNMENT_MODE_START}.
+ */
+ public void setMenuAlignmentMode(@MenuAlignmentMode int menuAlignmentMode) {
+ if (this.menuAlignmentMode != menuAlignmentMode) {
+ this.menuAlignmentMode = menuAlignmentMode;
+ ActionMenuView menu = getActionMenuView();
+ if (menu != null) {
+ translateActionMenuView(menu, fabAlignmentMode, isFabVisibleOrWillBeShown());
+ }
+ }
+ }
+
+ /**
+ * Returns the current menuAlignmentMode, either {@link #MENU_ALIGNMENT_MODE_AUTO} or {@link
+ * #MENU_ALIGNMENT_MODE_START}.
+ */
+ @MenuAlignmentMode
+ public int getMenuAlignmentMode() {
+ return menuAlignmentMode;
+ }
+
public void setBackgroundTint(@Nullable ColorStateList backgroundTint) {
DrawableCompat.setTintList(materialShapeDrawable, backgroundTint);
}
@@ -1023,7 +1067,8 @@ protected int getActionMenuViewTranslationX(
@NonNull ActionMenuView actionMenuView,
@FabAlignmentMode int fabAlignmentMode,
boolean fabAttached) {
- if (fabAlignmentMode != FAB_ALIGNMENT_MODE_END || !fabAttached) {
+ if (menuAlignmentMode != MENU_ALIGNMENT_MODE_START
+ && (fabAlignmentMode != FAB_ALIGNMENT_MODE_END || !fabAttached)) {
return 0;
}
@@ -1034,8 +1079,8 @@ protected int getActionMenuViewTranslationX(
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
boolean isAlignedToStart =
- view.getLayoutParams() instanceof Toolbar.LayoutParams
- && (((Toolbar.LayoutParams) view.getLayoutParams()).gravity
+ view.getLayoutParams() instanceof LayoutParams
+ && (((LayoutParams) view.getLayoutParams()).gravity
& Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK)
== Gravity.START;
if (isAlignedToStart) {
diff --git a/lib/java/com/google/android/material/bottomappbar/res-public/values/public.xml b/lib/java/com/google/android/material/bottomappbar/res-public/values/public.xml
index e6bfad40f4a..daccc88a883 100644
--- a/lib/java/com/google/android/material/bottomappbar/res-public/values/public.xml
+++ b/lib/java/com/google/android/material/bottomappbar/res-public/values/public.xml
@@ -22,6 +22,7 @@
+
diff --git a/lib/java/com/google/android/material/bottomappbar/res/values/attrs.xml b/lib/java/com/google/android/material/bottomappbar/res/values/attrs.xml
index 51e1ce42d84..a1d0eae715f 100644
--- a/lib/java/com/google/android/material/bottomappbar/res/values/attrs.xml
+++ b/lib/java/com/google/android/material/bottomappbar/res/values/attrs.xml
@@ -58,6 +58,14 @@
+
+
+
+
+
+
+