Add a Toolbar Elevation on pre Lollipop
Being a Material Design lover, I get put off by that default flat Toolbar with no shadow or elevation. It’s alright on Lollipop devices as it gives us a nice shadow by default, but pre Lollipop doesn’t. While that’s too bad, we can take care of that real quick!
After you’re done with this post, your Toolbars on pre Lollipop will never be plain and boring again!
Also read: Create a Card Toolbar (Nested Toolbar).
Faking a Toolbar Elevation
Since we can’t use the actual Toolbar elevation property for pre Lollipop devices, we’ll imitate one by using :
- 9-patch PNG
- XML gradient
Personally, I find the XML method more clean, so we’ll go with the second one.
Shadow Drawable
Create a new XML file res/drawable/shadow.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="@android:color/transparent" android:endColor="#40000000" android:angle="90" /> </shape>
Here we set a gradient from top to bottom of an opacity of black to transparent respectively.
Creating the Toolbar
Now the trick doesn’t lie in modifying the Toolbar as such, but in simply adding a View below it.
Usually we may define a Toolbar in a separate XML file and call it in via the <include /> tag. We’ll stick to the same format (to avoid large and complex layouts).
Create a layout res/layout/toolbar_shadow.xml and add this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" /> <View android:layout_width="match_parent" android:layout_height="4dp" android:background="@drawable/shadow" /> </LinearLayout>
Calling it in
Now with that in place, all we need to do is to reference this in our activity’s layout like this:
<include layout="@layout/toolbar_shadow" />
That’s it we’re done! Take a look at the results yourself and see the difference.
on pre Lollipop
Toolbar Elevation on Lollipop
You can default to the elevation property for Lollipop devices. Now in some cases, as with the new Design support library’s new widgets, after the animation the Toolbars by default have a shadow. So do the Tabs.
You could reference the shadow’s View via an id, and removing it with:
shadowView.setVisibility(View.GONE);
Then set the Toolbar elevation with
toolbar.setElevation(4);
But Wait!
In my opinion, just stick to using the shadow.xml on both pre Lollipop and Lollipop devices. Why? The difference isn’t much and is hardly noticeable.
This is a better trade-off than having to handle it in code, where you must remove the shadow view, then elevate it. That is just a lot of code handling and possible layout inconsistency, you’re much better off this way. One must not waste time as a developer to get something like that to work.
With this way, you can now mimic an elevation for your Toolbars on pre Lollipop as well. We created a shadow drawable in XML using a gradient property. Also you’ve probably accepted the fact that its okay to continue using the same drawable on post Lollipop as well, being a well worth sacrifice.
Do subscribe (below) for instant updates as I continue to bring you more awesome content like this!
Product Designer who occasionally writes code.
great work!
nice ! !
Hey.
So I tried this out, and came across a little quirk – the content was not going “under” the XML shadow we put in, like it is supposed to when we set elevation. My first instinct was to apply a negative margin to the parent LinearLayout in the toolbar XML, and it worked just as I expected it to.
I find this to be an elegant solution:
// Parent frame
// Actual layout content
The key lies in placing your include tag at the bottom most in a FrameLayout and then using a marginTop attribute for your actual content. If you’re using RelativeLayout for instance, place the include tag as the top-most child.
Hi!
This solution is super clean, I just change it a bit and included the margin in the view with the shadow instead. But I wouldn’t even think about this before this post.
Thank you and keep up these excellent posts.
Hey there!
Glad the post helped you out.
Hello, I was able to do this design but when i try add the support tool bar in my java code, i get casting exceptions because this approach requires the toolbar to be encapsulated within a LinearLayout. How do I work around this?
Hi Tshepo,
Great to see you again. I personally implement all this to ensure it works, before posting. I didn’t run into any such issues.
From the looks of it, you must set the support toolbar by using the TOOLBAR id which resides inside the LinearLayout. You must NOT reference the LinearLayout id as the toolbar itself.
Hope that helped. Otherwise please post your code somewhere so I can take a look.
Cheers.
Dude! You are like an alien or something, so smart.. Thanks a lot man, worked like a charm! Keep up on the awesome posts, you making android for beginners like me such a breeze
I’m very much human. I can guarantee you that! 😉
Good to know that it helps.
Cheers!
Can you put an easy to find date on your posts?
Hi Jeremy,
Dates have been added. It can be found at the bottom of the post excerpt.