When upgrading from the Android Support Library v23.4.0 to v24.0.0, setting the elevation to 0 programmatically to an AppBarLayout stopped working:
appBayLayout.setElevation(0);
It does work when setting the elevation in the XML.
When upgrading from the Android Support Library v23.4.0 to v24.0.0, setting the elevation to 0 programmatically to an AppBarLayout stopped working:
appBayLayout.setElevation(0);
It does work when setting the elevation in the XML.
Edit
The AppBarLayout
from v24.0.0 uses a StateListAnimator
that defines the elevation depending on its state. So using setElevation
will have no effect if a StateListAnimator
is being used (which happens by default). Set the elevation
via the XML or programmatically (both for API >= 21):
StateListAnimator stateListAnimator = new StateListAnimator();
stateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));
appBarLayout.setStateListAnimator(stateListAnimator);
Old answer
This seems to be an issue of the design support library. The problem is related to the way the elevation is set programmatically, using setElevation
. Setting it from the XML is placing a StateListAnimator
in the view and not calling setElevation
. However, setElevation
should work.
Here there is a workaround:
setDefaultAppBarLayoutStateListAnimator(appBarLayout, 0);
@SuppressLint("PrivateResource")
private static void setDefaultAppBarLayoutStateListAnimator(final View view, final float targetElevation) {
final StateListAnimator sla = new StateListAnimator();
// Enabled, collapsible and collapsed == elevated
sla.addState(new int[]{android.R.attr.enabled, android.support.design.R.attr.state_collapsible,
android.support.design.R.attr.state_collapsed},
ObjectAnimator.ofFloat(view, "elevation", targetElevation));
// Enabled and collapsible, but not collapsed != elevated
sla.addState(new int[]{android.R.attr.enabled, android.support.design.R.attr.state_collapsible,
-android.support.design.R.attr.state_collapsed},
ObjectAnimator.ofFloat(view, "elevation", 0f));
// Enabled but not collapsible == elevated
sla.addState(new int[]{android.R.attr.enabled, -android.support.design.R.attr.state_collapsible},
ObjectAnimator.ofFloat(view, "elevation", targetElevation));
// Default, none elevated state
sla.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));
view.setStateListAnimator(sla);
}
This is taken from what the constructor does, calling a method in the class ViewUtilsLollipop
in v24.0.0.
One more possible solution for this is to add android:stateListAnimator="@null"
to your AppBarLayout
as shown below.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stateListAnimator="@null"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
appBarLayout.setElevation(0)
and appBarLayout.setStateListAnimator(null)
to disable elevation and appBarLayout.setElevation(10.5)
to enable. It worked in run time and after screen rotation –
Lamebrain In my case I needed to change elevation of AppBarLayout
in runtime and setElevation(..)
did the trick.
However after screen rotation and calling setElevation(..)
from onCreateOptionMenu
didn't work, but setStateListAnimator(null)
did the trick.
Therefore I got this logic:
public final float appBarElevation = 10.5f;
public void disableAppBarElevation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
appBarLayout.setElevation(0);
appBarLayout.setStateListAnimator(null);
}
}
public void enableAppBarElevation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
appBarLayout.setElevation(appBarElevation);
}
}
© 2022 - 2024 — McMap. All rights reserved.
view
is used in your examplestateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));
? – Lowlife