This is a simple question:
I use the new support library, which allows me to have a Toolbar instance and even set it as the actionBar of the activity (or use the default one).
How do I customize the shadow being cast by the Toolbar (or the default ActionBar) ?
I've tried to use "setElevation" (on both of them), but it didn't seem to do anything on Android Lollipop.
Also, I can't find how to customize the shadow on pre-Lollipop versions. Is there maybe an API for this? or at least a drawable (I didn't find, even though I've tried) ?
OK, I've managed to find the next things:
For both Lollipop and pre-Lollipop, when your activity uses the normal AppCompat themes (like "Theme.AppCompat.Light" for example) , the shadow should look well.
However, when you use "setSupportActionBar" (and use an appropriate theme, like "Theme.AppCompat.Light.NoActionBar" for example) , you will have some issues with the shadow.
For pre-Lollipop, you can put a FrameLayout below the toolbar, that will look exactly like the one used for the normal themes, as such:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:foreground="?android:windowContentOverlay"
android:visibility="@integer/action_bar_shadow_background_visibility" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:text="@string/hello_world" />
</RelativeLayout>
You can use the FrameLayout as your content of the activity, or use what I've done. You can also set its visibility by putting integer 0 for pre-lollipop and 2 for Lollipop and above, as I've done with "action_bar_shadow_background_visibility".
It's an ugly solution, but it works, but only for pre-Lollipop versions.
In any case, I still couldn't find a way to show the shadow well for Lollipop, in case I use "setSupportActionBar". I tried using "setElevation" on the toolbar and the actionbar (using "getSupportActionBar", right after calling "setSupportActionBar") .
I also don't get how to get the standard height of the actionbar , as I noticed that a lot of tutorial say to use "minHeight" for the toolbar. Would appreciate help for this too.
Can anyone help me with this?
Again, to make it clear, this is what I ask:
- for Pre-Lollipop, show the same shadow that's used on the support library for both Toolbar and ActionBar.
- Same for Lollipop (but use the one that Lollipop has)
- Extra: customize the shadow to be more "delicate" on Lollipop (and maybe customize it on all versions).
- Extra: why does the minHeight of the toolbar get a value of the action bar height, instead of the height itself?
EDIT: OK, this is as far as I've done so far to mimic the shadow of Lollipop :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
layout="@layout/toolbar_action_bar_shadow" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:text="@string/hello_world" />
</RelativeLayout>
res/layout/toolbar_action_bar_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:windowContentOverlay" />
res/layout-v21/toolbar_action_bar_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/msl__action_bar_shadow" />
res/drawable-v21/res/layout/msl__action_bar_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- intended for lollipop and above -->
<item>
<shape
android:dither="true"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#00000000"
android:startColor="#33000000" />
<size android:height="10dp" />
</shape>
</item>
</layer-list>
It's not exactly the same, but it's similar.
EDIT: I still don't know why it happens. I think the code I've written on the question is misleading, as all there is to do is to set a background. Yet on the app I'm testing it still doesn't help. The app I'm trying to fix has the toolbar above the navigation drawer.
For a moment I thought that it might be because I've made a customized toolbar (which extends from Toolbar) and that changes its alpha value (according to the navigation drawer), but even if I use the normal toolbar and disable everything that's related to alpha, it still doesn't work. Also, not only that, but on a totally new project, I've tried to set a semi-transpared background for the toolbar, and it got a shadow according to the "setElevation" method.
Now it's even harder for me to find the cause for this problem, because it seems it's not because of transparency and not because of a custom Toolbar class...
Here's the layout of the activity that has the toolbar, in case this can help in any way:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.widget.DrawerLayout
android:id="@+id/activity_main__drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/activity_main__fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:layout_marginTop="?attr/actionBarSize"
layout="@layout/activity_main__sliding_menu" />
</android.support.v4.widget.DrawerLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.app.ui.Toolbar
android:id="@+id/activity_main__toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:layoutDirection="ltr"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
tools:ignore="UnusedAttribute" />
<!-- <include -->
<!-- android:layout_width="match_parent" -->
<!-- android:layout_height="wrap_content" -->
<!-- layout="@layout/toolbar_action_bar_shadow" /> -->
</LinearLayout>
</FrameLayout>
This is what I have done in one of my apps, it's showing shadow (artificial shadow) :
toolbar_dropshadow.xml :
I am using a map activity and all this is showing wonderful shadow on my map view.
Hope this helps...
As far as I know/can read, the AppCompat library currently does not render any shadows. The calls seem to be there (e.g.
ViewCompat.setElevation(View view, float elevation)
) but it doesn't seem to be doing anything.So I guess you will need to resort to adding your own shadows for now, at least until the support library implements the shadow rendering.
Looking at the Google IO 2014 source code, they have implemented like this:
More information on this Reddit Thread and stackoverflow.