Search code examples
androidandroid-layoutandroid-toolbarandroid-stylesandroid-appbarlayout

Adding custom shadow in AppBarLayout under TabLayout?


I've added a custom shadow below my TabLayout in AppBarLayout, but for some reason, there's a green background underneath the shadow:

enter image description here

In case that's not clear enough, here it is again with a longer shadow:

enter image description here

As you can see, there's a green background underneath the shadow and I'm not sure how to get rid of it.

Then I noticed, in the Design tab, that the AppBarLayout's background was set to green (even though it's not set to any color in the layout's XML):

enter image description here

I tried changing the color to @android:color/transparent, but it made the background (behind the shadow like in the above pictures) white, and not transparent. So I'm still not sure what's going on.

Here's my layout:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:elevation="0dp">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            app:layout_scrollFlags="scroll|enterAlways"
            app:tabBackground="@color/colorPrimary"
            app:tabIndicatorColor="@android:color/white"
            app:tabSelectedTextColor="@android:color/white"
            app:tabTextAppearance="@style/TabTextAppearance"
            app:tabTextColor="@color/colorTabText" />

        <View
            android:layout_width="match_parent"
            android:layout_height="8dp"
            android:background="@drawable/toolbar_shadow" />

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

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

Here is toolbar_shadow.xml drawable:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient
        android:startColor="@android:color/transparent"
        android:endColor="@color/shadowColor"
        android:angle="90" />

</shape>

And here is the color (20% opacity):

<color name="shadowColor">#33423f3f</color>

What am I doing that's wrong?


Solution

  • AppBarLayout has default background ?colorPrimary. Clear it by setting android:background="@null".

    Which brings us to the question you're going to ask tomorrow:

    Why content does not draw underneath my custom shadow?

    To which I say use the power of CoordinatorLayout and put the shadow outside of the AppBarLayout.

    styles.xml

    <style name="Widget.Shadow.AppBar" parent="">
        <item name="android:background">@drawable/toolbar_shadow</item>
        <item name="android:layout_height">4dp</item>
        <item name="android:layout_width">match_parent</item>
        <item name="layout_anchorGravity">bottom</item>
        <item name="android:layout_gravity">bottom</item>
    </style>
    

    layout.xml

    <CoordinatorLayout>
        <AppBarLayout android:id="@+id/appbar">
            <Toolbar/>
            <TabLayout/>
        </AppBarLayout>
        <ViewPager/>
        <View 
            style="@style/Widget.Shadow.AppBar"
            app:layout_anchor="@id/appbar"/>
    </CoordinatorLayout>
    

    Put the custom shadow view at the end so it draws over the content underneath.

    Explanation: By using this code you declare that you want the shadow view to

    • draw below (android:layout_gravity="bottom")
    • the bottom edge (app:layout_anchorGravity="bottom")
    • of the App Bar (app:layout_anchor="@id/appbar")