ToolBar disappears when setting elevation for AppBarLayout - android

My ToolBar disappears when setting elevation for AppBarLayout. Here's the layout.
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/appbar_height"
app:elevation="0dp"
android:background="#color/transparent">
<android.support.v7.widget.Toolbar
style="#style/ToolBarStyle"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:background="#drawable/backgorund_toolbar_tranluscent"
android:minHeight="#dimen/abc_action_bar_default_height_material" />
</android.support.design.widget.AppBarLayout>
I have tried values like 0dp, 0.1dp and 4dp for app:elevation. What's happening here? Is it a support library bug? I'm using 24.0.0.

Answer from #Zeeshan is totally right.
as an extra here is a sample code that works
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
StateListAnimator stateListAnimator = new StateListAnimator();
stateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(appBarLayout, "elevation", 0.1f));
appBarLayout.setStateListAnimator(stateListAnimator);
}
I had to set elevation to 0.1 because setting it to 0 wasn't working, the whole Layout was disappearing.

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

Related

Shadow problem Floating Action Button (api = 19)

I had a problem with FAB shadow on API <= 19. I used compatElevation= 0f and shadow disappeared. But it appears again during onClick and looks strange:
XML code:
<android.support.design.widget.FloatingActionButton
android:id="#+id/RateBtn"
android:layout_width="#dimen/backet_Btn_size"
android:layout_height="#dimen/backet_Btn_size"
android:elevation="0dp"
app:elevation="0dp"
android:clickable="true"
android:focusable="true"
android:src="#drawable/star_rate2"
app:backgroundTint="#color/w"
app:layout_constraintEnd_toEndOf="#+id/langBtn2"
app:layout_constraintStart_toStartOf="#+id/langBtn2"
app:layout_constraintTop_toTopOf="#+id/SettingsBtn"
app:rippleColor="#color/grey_700" />
Code:
var fb = view?.findViewById(R.id.RateBtn) as FloatingActionButton
val lp =it.layoutParams
if (lp !=null){
lp.width= size_fb
lp.height=size_fb
it.customSize=size_fb
it.layoutParams= lp
}
I think there is some problem when I try to change FAB size programmatically. When I set size in xml, everything is ok
use this code
android:elevation="0dp"
app:elevation="0dp"
Override the default elevation of the FAB by adding
android:elevation="0dp"
Java
setStateListAnimator(null);
XML
android:stateListAnimator="#null"

Why there is no shadow under AppBarLayout despite having elevation [duplicate]

I've created an AppBar layout like this
<android.support.design.widget.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/appbar_layout"
android:layout_height="#dimen/app_bar_height"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="20dp">
<android.support.design.widget.CollapsingToolbarLayout...>
</android.support.design.widget.AppBarLayout>
it works and casts a shadow in the LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</LinearLayout>
However when I put it into the CoordinatorLayout shadow is gone:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</android.support.design.widget.CoordinatorLayout>
How can I make appbar to show its shadow again?
This is actually an implementation detail of CollapsingToolbarLayout, as seen in the source code:
if (Math.abs(verticalOffset) == scrollRange) {
// If we have some pinned children, and we're offset to only show those views,
// we want to be elevate
ViewCompat.setElevation(layout, layout.getTargetElevation());
} else {
// Otherwise, we're inline with the content
ViewCompat.setElevation(layout, 0f);
}
Which removes the elevation when the CollapsingToolbarLayout is showing non-pinned elements - by default, it'll only have elevation when only pinned children are visible.
the reason is above,try this to solve:
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//some other code here
ViewCompat.setElevation(appBarLayout, The Elevation In Px);
}
});
The solution is to use app:elevation=0dp to remove the default elevation and set android:translationZ to the elevation you want.
Note : The code below uses the latest AndroidX / Material libraries and might not work if you're using the old support library
<com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:translationZ="8dp"
app:elevation="0dp">
<!--
* `app:elevation=0dp` disables the default shadow that is automatically added on
scroll ; other values e.g. `6dp` are ignored despite what the official doc says
(see below)
* so instead we're using `android:translationZ` to add a shadow with a custom
elevation
-->
The documentation for AppBarLayout # setTargetElevation() states that you can set a custom elevation value using the app:elevation attribute, but it didn't work for me for values greater than 0dp, so I'm using translationZ as a workaround.
setTargetElevation() is now deprecated for AppBarLayout.
The new correct implementation for applying custom elevation to an AppBarLayout based on the state of the layout is to use a StateListAnimator.
material-components uses this as you can see here
I've added an example implementation of always showing AppBarLayout elevation here in this gist.
All you need is to 1. create a custom state list animator under /res/animator and 2. set the AppBarLayout's StateListAnimator like so:
appBarLayout.stateListAnimator = AnimatorInflater.loadStateListAnimator(context, R.animator.appbar_always_elevated_state_list_animator)

CollapsingToolbarLayout - shadow only when scrolled [duplicate]

I've created an AppBar layout like this
<android.support.design.widget.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/appbar_layout"
android:layout_height="#dimen/app_bar_height"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="20dp">
<android.support.design.widget.CollapsingToolbarLayout...>
</android.support.design.widget.AppBarLayout>
it works and casts a shadow in the LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</LinearLayout>
However when I put it into the CoordinatorLayout shadow is gone:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</android.support.design.widget.CoordinatorLayout>
How can I make appbar to show its shadow again?
This is actually an implementation detail of CollapsingToolbarLayout, as seen in the source code:
if (Math.abs(verticalOffset) == scrollRange) {
// If we have some pinned children, and we're offset to only show those views,
// we want to be elevate
ViewCompat.setElevation(layout, layout.getTargetElevation());
} else {
// Otherwise, we're inline with the content
ViewCompat.setElevation(layout, 0f);
}
Which removes the elevation when the CollapsingToolbarLayout is showing non-pinned elements - by default, it'll only have elevation when only pinned children are visible.
the reason is above,try this to solve:
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//some other code here
ViewCompat.setElevation(appBarLayout, The Elevation In Px);
}
});
The solution is to use app:elevation=0dp to remove the default elevation and set android:translationZ to the elevation you want.
Note : The code below uses the latest AndroidX / Material libraries and might not work if you're using the old support library
<com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:translationZ="8dp"
app:elevation="0dp">
<!--
* `app:elevation=0dp` disables the default shadow that is automatically added on
scroll ; other values e.g. `6dp` are ignored despite what the official doc says
(see below)
* so instead we're using `android:translationZ` to add a shadow with a custom
elevation
-->
The documentation for AppBarLayout # setTargetElevation() states that you can set a custom elevation value using the app:elevation attribute, but it didn't work for me for values greater than 0dp, so I'm using translationZ as a workaround.
setTargetElevation() is now deprecated for AppBarLayout.
The new correct implementation for applying custom elevation to an AppBarLayout based on the state of the layout is to use a StateListAnimator.
material-components uses this as you can see here
I've added an example implementation of always showing AppBarLayout elevation here in this gist.
All you need is to 1. create a custom state list animator under /res/animator and 2. set the AppBarLayout's StateListAnimator like so:
appBarLayout.stateListAnimator = AnimatorInflater.loadStateListAnimator(context, R.animator.appbar_always_elevated_state_list_animator)

CoordinatorLayout and AppBarLayout elevation

I've created an AppBar layout like this
<android.support.design.widget.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/appbar_layout"
android:layout_height="#dimen/app_bar_height"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="20dp">
<android.support.design.widget.CollapsingToolbarLayout...>
</android.support.design.widget.AppBarLayout>
it works and casts a shadow in the LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</LinearLayout>
However when I put it into the CoordinatorLayout shadow is gone:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/app_bar_large" />
</android.support.design.widget.CoordinatorLayout>
How can I make appbar to show its shadow again?
This is actually an implementation detail of CollapsingToolbarLayout, as seen in the source code:
if (Math.abs(verticalOffset) == scrollRange) {
// If we have some pinned children, and we're offset to only show those views,
// we want to be elevate
ViewCompat.setElevation(layout, layout.getTargetElevation());
} else {
// Otherwise, we're inline with the content
ViewCompat.setElevation(layout, 0f);
}
Which removes the elevation when the CollapsingToolbarLayout is showing non-pinned elements - by default, it'll only have elevation when only pinned children are visible.
the reason is above,try this to solve:
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//some other code here
ViewCompat.setElevation(appBarLayout, The Elevation In Px);
}
});
The solution is to use app:elevation=0dp to remove the default elevation and set android:translationZ to the elevation you want.
Note : The code below uses the latest AndroidX / Material libraries and might not work if you're using the old support library
<com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:translationZ="8dp"
app:elevation="0dp">
<!--
* `app:elevation=0dp` disables the default shadow that is automatically added on
scroll ; other values e.g. `6dp` are ignored despite what the official doc says
(see below)
* so instead we're using `android:translationZ` to add a shadow with a custom
elevation
-->
The documentation for AppBarLayout # setTargetElevation() states that you can set a custom elevation value using the app:elevation attribute, but it didn't work for me for values greater than 0dp, so I'm using translationZ as a workaround.
setTargetElevation() is now deprecated for AppBarLayout.
The new correct implementation for applying custom elevation to an AppBarLayout based on the state of the layout is to use a StateListAnimator.
material-components uses this as you can see here
I've added an example implementation of always showing AppBarLayout elevation here in this gist.
All you need is to 1. create a custom state list animator under /res/animator and 2. set the AppBarLayout's StateListAnimator like so:
appBarLayout.stateListAnimator = AnimatorInflater.loadStateListAnimator(context, R.animator.appbar_always_elevated_state_list_animator)

remove shadow below AppBarLayout widget android

When using AppBarLayout widget in design support library, a shadow appears on the bottom of the toolbar. How can I remove that shadow?
Simply use app:elevation="0dp" inside "AppBarLayout" to remove the shadow. It has always worked for me. Hope it works for you.
this problem only occurs when api version >= 21, try below codes:
appBar.setOutlineProvider(null);
remember to check api version
EDIT :
Below is the source code of setOutlineProvider.
/**
* Sets the {#link ViewOutlineProvider} of the view, which generates the Outline that defines
* the shape of the shadow it casts, and enables outline clipping.
* <p>
* The default ViewOutlineProvider, {#link ViewOutlineProvider#BACKGROUND}, queries the Outline
* from the View's background drawable, via {#link Drawable#getOutline(Outline)}. Changing the
* outline provider with this method allows this behavior to be overridden.
* <p>
* If the ViewOutlineProvider is null, if querying it for an outline returns false,
* or if the produced Outline is {#link Outline#isEmpty()}, shadows will not be cast.
* <p>
* Only outlines that return true from {#link Outline#canClip()} may be used for clipping.
*
* #see #setClipToOutline(boolean)
* #see #getClipToOutline()
* #see #getOutlineProvider()
*/
public void setOutlineProvider(ViewOutlineProvider provider) {
mOutlineProvider = provider;
invalidateOutline();
}
It is said that If the ViewOutlineProvider is null, if querying it for an outline returns false, or if the produced Outline is {#link Outline#isEmpty()}, shadows will not be cast.
So, if you want to remove shadow, you'd better use this method instead of setting app:elevation. It seems like that changing the elevation to remove shadow is a kind of side effect. And changing the elevation may cause some other problems in some cases.
For all those who do not want to use bringToFront() and elevation="0dp" makes the toolbar disappear:
app:elevation="0dp" combinded with android:translationZ="0.1dp" worked for me.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
app:elevation="0dp"
android:translationZ="0.1dp"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#null"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
With latest appcompat versions, the trick setting app:elevation="0.1dp" in xml doesn't work any more.
So far I have found two solutions.
Instead of setting app:elevation, try to use a stateListAnimator. For example, in code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
StateListAnimator stateListAnimator = new StateListAnimator();
stateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(appBarLayout, "elevation", 0.1f));
appBarLayout.setStateListAnimator(stateListAnimator);
}
An easier way is you still set app:elevation="0dp" in xml as normal, but in code:
appBarLayout.bringToFront();
Credit goes to these two discussions:
ToolBar disappears when setting elevation for AppBarLayout
when set app:elevation="0dp" then hamburgermenu not showing to toolbar
Use android:stateListAnimator="#null". No side effect.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:stateListAnimator="#null"
>
I tried app:elevation="0dp" but the toolbar desappear, but using app:elevation="0.1dp" made the trick.
Hope this helps somebody else.
Add app:elevation="0dp" on your AppBarLayout. like this example
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
Programmatically you can use this :
getSupportActionBar().setElevation(0.0f);
This is the way that I came up with app:elevation="0dp" to remove the shadow.Perfectly works.
I am doing this on Kotlin minSdkVersion 21 with AppBarLayout & TabLayout so: app:elevation="0dp" does indeed help me solve the shadow problem BUT using this solution make it so that I will not be able to press the button on the TabLayout.
so combine app:elevation="0.1dp" & app:elevation="0dp"i can fix the shadow and still be able to interact with my tab layout.

Categories

Resources