A place for BottomAppBar

Lubos Mudrak
2 min readMar 15, 2018

Last week as Google announced release of Android P preview they also release first alpha version of new support library that includes, amongst many interesting changes, new additions to design support library. From now on the library will include new MaterialButton, MaterialCardView, layout for Chips and BottomAppBar, also I hope we’ll get BackLayerLayout in future releases.

BottomAppBar, being an extensions of Toolbar, feels like a compromise to provide user with some actions comfortably without the need to reach for them with thumb in the Toolbar on top on devices with bigger screen.

It comes with semi-circular cutout that cradles the attached FloatingActionButton with options to set cradleDiameter, roundedCornerRadius and vertical offset of our FloatingActionButton which, if set, would change the semi-circle into arc.
For positioning the attached FloatingActionButton we can choose one of two alignment modes FAB_ALIGNMENT_MODE_CENTER or FAB_ALIGNMENT_MODE_END

Default (center) alignment

Setup seems to be straightforward (unless I’ve missed something obvious). Just place the the BottomAppBar and FloatingActionButton into parent CoordinatorLayout and set app:layout_anchor attribute of FloatingActionButton to reference id of BottomAppBar.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.design.bottomappbar.BottomAppBar
android:id="@+id/bottom_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:fabAttached="true"
app:backgroundTint="@color/colorPrimary"
app:fabCradleVerticalOffset="12dp">

</android.support.design.bottomappbar.BottomAppBar>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_add_white_24dp"
app:layout_anchor="@+id/bottom_appbar"/>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.button.MaterialButton
android:id="@+id/toggle_alignment"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center"
android:textColor="#fff"
android:text="Toggle FAB alignment"
app:backgroundTint="@color/colorPrimary"/>

</FrameLayout>

</android.support.design.widget.CoordinatorLayout>

To set menu options you can provide Menu resource to your BottomAppBar in code by calling BottomAppBar.replaceMenu(R.menu.xxx) and to toggle the alignment I created a simple extensions function

import kotlinx...bottom_appbar
import kotlinx...fab
import kotlinx...toggle_alignment
// using kotlin-android-extensions here for findViewById calls
class BottomAppBarActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.actvity_bottom_appbar)

//setSupportActionBar(bottom_appbar) calling this breaks it!
// setting the menu
bottom_appbar.replaceMenu(R.menu.bottom_appbar_menu)
toggle_alignment.setOnClickListener {
bottom_appbar.toggleAlignment()
}
}
fun BottomAppBar.toggleAlignment() {
val current = fabAlignmentMode
fabAlignmentMode
= current.xor(1)
}
}

As mentioned before, since we have two alignment modes, one can toggle between them with some nice animation

Toggling the FAB alignment

Some notes to takeaway:

  • Don’t call setSupportActionBar() with your provided BottomAppBar as it will break it
  • To change the background colour you should call app:backgroundTint instead of setBackground because of internal management of background
  • Calling setTitle or setSubtitle will have no effect as these methods are overriden and empty

--

--