Add elevation/shadow on toolbar for pre-lollipop devices
Solution 1
For Android 5.0 and above : AppBarLayout automatically provides/gives shadow in the layout.
You can also increase the elevation of the AppBarLayout by app:elevation="4dp"
.
For Pre-Lollipop : You can use the following link: https://github.com/vipulasri/Toolbar-Elevation-Pre-Lollipop
Note: Toolbar also supports elevation to it, using android:elevation="4dp"
New Update: In Appcompat v24.0.0, you can not set elevation to AppBarLayout using setElevation()
and app:elevation
as these are deprecated.
You have to use stateListAnimator
property to set elevation now.
Note: set duration to 1ms in StateListAnimator
in order to avoid delay in Elevation Drawing.
AppBarLayout elevation change is delayed on appCompat v24.0.0
appbar_always_elevated.xml in animator-v21 folder under res directory.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<objectAnimator android:propertyName="elevation"
android:valueTo="8dp"
android:valueType="floatType"
android:duration="1"/>
</item>
</selector>
In AppbarLayout :
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:fitsSystemWindows="true"
android:stateListAnimator="@animator/appbar_always_elevated"
android:theme="@style/AppTheme.AppBarOverlay">
</android.support.design.widget.AppBarLayout>
Solution 2
Try using the AppBarLayout inside the activity layout. Try:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/Toolbar" />
</android.support.design.widget.AppBarLayout>
<fragment
class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment"
android:id="@+id/PlanningFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
Solution 3
use build file:
compile 'com.android.support:cardview-v7:23.1.1'
to call in xml add:
app:cardElevation="8dp"
app:cardCornerRadius="8dp"
app:contentPadding="5dp"
Solution 4
I think the best solution is to put a gradient shadow view below the toolbar and manipulate with visibility depends on device sdk.
toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<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 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/white"
android:fitsSystemWindows="true"
app:popupTheme="@style/AppTheme.PopupOverlay">
<TextView
android:id="@+id/centerTitleToolbarTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:textColor="@color/color_toolbar"
android:textSize="@dimen/titleToolbar" />
</android.support.v7.widget.Toolbar>
<View
android:id="@+id/shadow_view"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="4dp"
android:background="@drawable/toolbar_shadow" />
</LinearLayout>
toolbar_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#c1c1c1"
android:centerColor="#e6e6e6"
android:endColor="#f1f1f1"
android:angle="270" />
</shape>
MainActivity.class
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
findViewById(R.id.shadow_view).setVisibility(View.VISIBLE);
}
Solution 5
I have a CollapsingToolbarLayout
with Toolbar
and a Toolbar-like View
that moves up and down, but lays above NestedScrollView
, like in https://github.com/k0shk0sh/CoordinatorLayoutExample.
I tried many variants. Sometimes a shadow scrolled above a screen with NestedScrollView, sometimes the Toolbar drew a solid shadow without transparency, sometimes the shadow was aliased. Anyway, this is my solution.
Say, you have a layout:
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar>
<!-- Toolbar views if needed -->
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- Footer Toolbar views if needed -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout>
<!-- Views -->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<!-- Add this view. It draws a shadow and aligns top of NestedScrollView -->
<!-- Set visibility to gone or visible -->
<View
android:id="@+id/scroll_shadow"
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="@drawable/shadow"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Add a shadow (drawable/shadow.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:endColor="#ffcccccc"
android:startColor="#00cccccc" />
</shape>
Add this method. Here scrollShadow is a view named "scroll_shadow":
private void setShadowVisibility(int visibility) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
scrollShadow.setVisibility(visibility);
}
}
Manipulate it as you wish. It will show a gradient on pre-Lollipop devices and shows a normal shadow for Android 5.0+.
Related videos on Youtube
avb
Updated on July 09, 2022Comments
-
avb almost 2 years
I updated my android app to the new material design, but I also wanted to add some shadow or elevation to the Toolbar. There seem to be some (hacky) ways of doing it via images/9-patches, but I wonder if it can be done via the support libraries. (just like the
CardView
can have elevation)According to this answer on another question, this is possible by wrapping the
Toolbar
in aAppBarLayout
, but this doesn't work for me.My layout:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.AppBarLayout 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.support.v7.widget.Toolbar android:id="@+id/Toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.AppBarLayout>
I also tried setting elevation via XML and through code, but that doesn't work either.
Any help would be appreciated! Thanks in advance.
Update:
Since I include my Toolbar layout in my other layouts, below is one of my main layouts:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/Toolbar" /> <fragment class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment" android:id="@+id/PlanningFragment" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
-
Binoy Babu almost 9 yearsAre you using <include> tags to include it in your activity layout? If yes, post your activity layout.
-
avb almost 9 years@BinoyBabu Yes, I use include tags. I updated my answer with the activity layout. Thanks for your time.
-
Ranjithkumar almost 9 yearsrefer my answer..stackoverflow.com/a/30962710/3879847
-
-
avb almost 9 yearsThat doesn't show shadow either in my case. I am using a phone with android 4.4.4 KitKat, if that helps. Thanks
-
Binoy Babu almost 9 yearsI'm at a loss then. I think you might have to use drop shadow in the fragment foreground for pre lollipop.
-
avb almost 9 yearsOk, weird that it works for you. Maybe it has to do with me using Xamarin, and it only works in the native support libary... I'll look at the other solutions then. Thanks for your help anyways, appreciate it.
-
Daisy almost 9 years@avb1994 I have the same issue and am using Xamarin as well. So it may well be a Xamarin issue. :-(
-
oli.G almost 8 yearsAdding app:elevation doesn't work for me on pre-Lollipop, whether I add it to the AppBarLayout or to the Toolbar
-
Vipul Asri almost 8 years@oli.G in that case you have to use second option.
-
Ali Bdeir almost 8 yearsThat link was unbelievably awesome. +1
-
iRuth almost 8 years@VipulAsri, the link (blog.grafixartist.com/add-a-toolbar-elevation-on-pre-lollipop) is broken.
-
Aspiring Dev about 7 yearsThe link isn't very useful if you apply this to the toolbar on an activity that has a list. The "shadow" completely hides the items when you start to scroll down and completely displaces highlight color at the top when you "overscroll" to the top. Not good.
-
Mohamed about 7 yearsThanks man!,
stateListAnimator
completely working from 21+, To use it programmatically do this:appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(context, R.animator.appbar_always_elevated));
. -
Trancer about 7 yearsThis answer is not solve the issue with shadow. It adds more problems only. See imgur.com/UrFLioZ
-
liorsolomon almost 7 yearsHey Rina, can you please explain what is the change you are suggesting? why would it solve the issue?
-
rina lakhani almost 7 yearsto elevate appbar in pre-lolipop device surround it with cardview and elevate cardview as per need. this will elevate appbar and shadow will be given automatically @liorsolomon
-
tasomaniac over 6 yearsWhat is
toolbar_shadow
you have in the code example. -
Ionut Negru over 6 yearsIt is an 9patch drawable resource.
-
David over 6 years@Trancer that was your error, the toolbar and the shadow should not share the same parent, it also happened to me.
-
aga over 6 yearsThat's like the worst solution I've ever seen.
-
CoolMind about 6 yearsTried this solution, it is suitable for
RecyclerView
andNestedScrollView
, for still and movingToolbar
.