Search code examples
androidmaterial-designbottomnavigationviewmaterial-componentsbottomappbar

BottomNavigationView inside a BottomAppBar with transparent background


I have been combining the new(ish) Material BottomAppBar with a standard BottomNavigationView. My xml is like this:

      <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:contentInsetStart="0dp"
        app:contentInsetStartWithNavigation="0dp"
        app:fabAlignmentMode="center">

        <com.google.android.material.bottomnavigation.BottomNavigationView
          android:id="@+id/bottom_navigation"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginStart="0dp"
          android:layout_marginEnd="0dp"
          android:background="@android:color/transparent"
          app:itemTextAppearanceActive="@style/AppTheme.Text.BottomNavText.Active"
          app:itemTextAppearanceInactive="@style/AppTheme.Text.BottomNavText"
          app:labelVisibilityMode="labeled"
          app:menu="@menu/bottom_nav_menu" />

      </com.google.android.material.bottomappbar.BottomAppBar>

On the previous version - 1.0.0 - this was working fine, and I could still see the FAB inset as expected. The only minor drawback is this version of the material components library hadn't sorted the elevation effect of the bottom app bar, and so the distinction between the bar and the content above wasn't clear.

When I upgrade to the latest library, which at the time of writing I believe is implementation 'com.google.android.material:material:1.1.0-alpha09', I get the BottomAppBar elevation effects, but when I apply the transparent background to the BottomNavigationView, I get a very strange visual effect that for the life of me I cannot understand.

Strange BottomAppBar effect

If I remove the transparent background color, then the effect goes but I lose the FAB inset, as below:

Bottom Nav without transparency, lose the inset effect

If I remove the bottom navigation view child altogether, and just have the BottomAppBar, I see the visual effect as normal, but without my navigation:

Without the bottom nav view as child, all works normal

I would love either: - A good solution to incorporate bottom navigation view inside a BottomAppBar while retaining version 1.1.0 libraries nice elevation effect, and also have the BottomNavigationView effectively inside it so I retain all the benefits of that navigation component - Or an explanation for what on earth is causing that peculiar first elevation effect, and ideally a way to fix it


Solution

  • Ok, this is nothing to do with BottomAppBar... the background problem happens on BottomNavigationView regardless of where it is, in material library 1.1.0- ....

    This is (I think) a bug with the recent version of BottomNavigationView in which it sets a tintable MaterialShapeDrawableBackground as its background if background is either null or a ColorDrawable... and when you set a color in xml, it will be a ColorDrawable (including transparent). Here is the issue in the BottomNavigationView code:

        if (getBackground() == null || getBackground() instanceof ColorDrawable) {
          // Add a MaterialShapeDrawable as background that supports tinting in every API level.
          ViewCompat.setBackground(this, createMaterialShapeDrawableBackground(context));
        }
    

    Which gets what must be the random shadow shape you see above.

    Solution

    The workaround is to set a background in the xml which is neither null or a ColorDrawable. I created my own drawable, which is just a transparent rectangle, and set that as the BottomNavigationView background, and it works.

    background_transparent.xml

    <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"
      android:padding="10dp"
      android:shape="rectangle" >
    
      <solid android:color="#00000000" />
    
    </shape>
    

    And now the updated BottomNavigationView xml:

            <com.google.android.material.bottomnavigation.BottomNavigationView
              android:id="@+id/bottom_navigation"
              style="@style/BottomNav"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_marginStart="0dp"
              android:layout_marginEnd="0dp"
              android:background="@drawable/background_transparent"
              app:itemTextAppearanceActive="@style/AppTheme.Text.BottomNavText.Active"
              app:itemTextAppearanceInactive="@style/AppTheme.Text.BottomNavText"
              app:labelVisibilityMode="labeled"
              app:menu="@menu/bottom_nav_menu" />
    
    

    And the result:

    enter image description here