How to set the elevation of an AppBarLayout programmatically in the Android Support Library v24.0.0?
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">