support last android android-support-library android-support-design

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.