last - ¿Cómo establecer la elevación de un AppBarLayout mediante programación en la biblioteca de soporte de Android v24.0.0?
com.android.support:support-v4 28 (3)
En mi caso, necesitaba cambiar la elevación de AppBarLayout
en tiempo de ejecución y setElevation(..)
hizo el truco.
Sin embargo, después de la rotación de la pantalla y de llamar a setElevation(..)
desde onCreateOptionMenu
no funcionó, pero setStateListAnimator(null)
hizo el truco.
Por lo tanto tengo esta lógica:
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);
}
}
Al actualizar desde la biblioteca de soporte de Android v23.4.0 a v24.0.0, la configuración de la elevación en 0 mediante programación a un objeto AppBarLayout dejó de funcionar:
appBayLayout.setElevation(0);
Funciona cuando se configura la elevación en el XML.
Una solución más posible para esto es agregar android:stateListAnimator="@null"
a su AppBarLayout
como se muestra a continuación.
<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">
Editar
El AppBarLayout
de v24.0.0 usa un StateListAnimator
que define la elevación dependiendo de su estado. Por lo tanto, el uso de setElevation
no tendrá ningún efecto si se StateListAnimator
un StateListAnimator
(lo que sucede de manera predeterminada). Establezca la elevation
mediante el XML o mediante programación (ambos para API> = 21):
StateListAnimator stateListAnimator = new StateListAnimator();
stateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));
appBarLayout.setStateListAnimator(stateListAnimator);
Vieja respuesta
Esto parece ser un problema de la biblioteca de soporte de diseño . El problema está relacionado con la forma en que la elevación se establece mediante programación, utilizando setElevation
. Establecerlo desde el XML es colocar un StateListAnimator
en la vista y no llamar a setElevation
. Sin embargo, setElevation
debería funcionar.
Aquí hay una solución:
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);
}
Esto se toma de lo que hace el constructor, llamando a un método en la clase ViewUtilsLollipop
en v24.0.0.