

Casting a shadow under views such as toolbars and bottom navigation is quite appealing for the end-user because it adds some depth to the UI and makes it look more dynamic. After much trouble of trying to figure out the best way to do this, I have come up with a solution – by creating a custom shape and adding it to the views programmatically.
The good thing about this approach is that you won’t have any compatibility issues. Devices running on pre-Lollipop (API 21) won’t be able to cast a shadow with an elevation attribute. Moreover, even if running on Lollipop or above, the default drop shadow which should be applied sometimes doesn’t work at all and it’s difficult to adjust the shade and gradient. I have noticed that some people try to do this by wrapping the toolbar or bottom navigation into a card view! How is that even legal?
Let us start by defining the shape and colour of the drop shadow.
@drawable/drop_shadow_toolbar
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="@android:color/transparent" android:endColor="#88333333" android:angle="90"/> </shape>
To achieve the proper shadow effect, we must create a gradient starting from transparent and ending with the desired colour such as dark grey. You can adjust the colour and shade accordingly.
In main_activity.xml we define the view like so:
For Relative Layouts:
<View android:layout_width="match_parent" android:layout_height="5dp" android:layout_below="@id/app_bar_layout" android:background="@drawable/drop_shadow_toolbar"
To anchor the view properly it depends on the root parent layout which you are using. If using a relative layout, the solution is as simple as the one above. We simply define layout_below and assign our app_bar_layout to it. But what if you are using a different layout such as Coordinator Layout?
For Coordinator Layouts
<RelativeLayout android:layout_width="match_parent" android:layout_height="10dp" app:layout_anchor="@id/collapsing_toolbar" app:layout_anchorGravity="bottom"> <View android:layout_width="match_parent" android:layout_height="5dp" android:layout_alignParentBottom="true" android:background="@drawable/drop_shadow_toolbar" /> </RelativeLayout>
If the root layout is Coordinator, the solution I have found is to wrap the view inside a relative layout and then anchor it to the collapsing toolbar layout.
Linear Layouts:
</com.google.android.material.appbar.AppBarLayout> <View android:layout_width="match_parent" android:layout_height="5dp" android:background="@drawable/drop_shadow_toolbar" />
Remember to set the orientation to vertical and then simply put the code under AppBarLayout.
Constraint Layouts: Add the following attribute:
app:layout_constraintTop_toBottomOf="@id/app_bar_layout"
Drop shadow for bottom navigation
If you want to add a drop shadow to your bottom navigation, the solution is quite simple. We just do things in reverse.
@drawable/bottom_nav_dropshadow
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#88333333" android:endColor="@android:color/transparent" android:angle="90" /> </shape>
We swap the start and end colour. The start is now our main shade and the end colour will be transparent because we want to go from bottom to top.
Coordinator layout:
<RelativeLayout android:layout_width="match_parent" android:layout_height="10dp" app:layout_anchor="@id/bottom_navigation" app:layout_anchorGravity="top"> <View android:layout_width="match_parent" android:layout_height="5dp" android:background="@drawable/bottom_nav_dropshadow" /> </RelativeLayout>
That’s it! If you have any suggestions to improve this please leave a comment below. You can access the full source code here.