android - personalizado - navigation drawer material design
¿Cómo restablecer la posición de la barra de herramientas controlada por el CoordinatorLayout? (7)
La aplicación en la que estoy trabajando consiste en un cajón de navegación que se implementa en una actividad. El diseño de la actividad es el siguiente:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
android:id="@+id/appbar"
layout="@layout/appbar" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header_drawer"
app:menu="@menu/menu_nav">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
Este es un patrón muy común, lo único que cambia con frecuencia es el Fragmento dentro del diseño del contenedor.
Si alguno de los Fragmentos tiene un elemento de desplazamiento, al desplazarse, el CoordinatorLayout hará con mucho gusto las traducciones de posición, incluida la Barra de herramientas / AppBarLayout.
El problema real aquí es que, cuando se reemplaza el Fragmento, la posición de la Barra de herramientas sigue siendo la misma, es decir, si la Barra de herramientas está oculta, se mantendrá, lo que no es la intención.
El resultado es este:
Esta:
Queda atascado:
¿Cómo se puede restablecer la posición de la barra de herramientas para este caso?
EDITAR: es probable que se produzca un error; se llama al oyente de cambio de compensación de AppBarLayout solo cuando se reinicia la aplicación (presiona el botón Atrás y abre la aplicación), y deja de ser llamado nuevamente después de un intenso tiroteo.
@razzledazzle The AppBarLayout almacena OnOffsetChangedListeners como WeakReferences, lo que significa que se recolectan basura cuando es necesario, por ejemplo, cuando se realiza una intensa aventura. Vea la solución aquí:
Actualice su biblioteca de soporte a v23 y luego puede usar:
appBarLayout.setExpanded(true/false);
public void setExpanded (booleano expandido )
Establece si esta AppBarLayout se expande o no, animando si ya se ha diseñado.
Al igual que con el desplazamiento de AppBarLayout, este método se basa en que este diseño es un elemento secundario directo de un CoordinatorLayout.
expandido verdadero si el diseño debe expandirse completamente, falso si debe estar completamente colapsado
Como dice el document
AppBarLayout soporta
void setExpanded (boolean expandido, boolean animate);
Establece si este AppBarLayout se expande o no.
- expandido booleano: verdadero si el diseño debería estar completamente expandido, falso si debería estar completamente colapsado
- animar booleano: si animar al nuevo estado
Así que al principio necesitas
AppBarLayout appBarLayout = (AppBarLayout)findViewById(R.id.appBarLayout);
luego para expandir el diseño
appBarLayout.setExpanded(true, true); // with animation
appBarLayout.setExpanded(true, false); // without animation
y colapsar diseño
appBarLayout.setExpanded(false, true); // with animation
appBarLayout.setExpanded(false, false); // without animation
Estoy usando estos códigos antes de los cambios de fragmentos.
scrollingElement.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
scrollingElement.dispatchNestedPreScroll(0, -Integer.MAX_VALUE, null, null);
scrollingElement.stopNestedScroll();
Para restablecer el estado de desplazamiento, solo obtenga el objeto AppBarLayout.Behavior
CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.coordinator);
AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
y llamar onNestedPreScroll
método onNestedPreScroll
manualmente:
int[] consumed = new int[2];
behavior.onNestedPreScroll(coordinator, appbar, null, 0, -1000, consumed);
Si desea restablecer sin problemas con una animación, puede intentar llamar a onNestedFling
en onNestedFling
lugar:
behavior.onNestedFling(coordinator, appbar, null, 0, -1000, true);
Primero obtenga una referencia de AppBarLayout en su MainActivity, luego en el estado de pausa del fragmento que se está reemplazando, use el método a continuación para expandir la barra de herramientas:
MainActivity.appbar.setExpanded(true,true);
Y o para cerrar la barra de herramientas:
MainActivity.appbar.setExpanded(false,true);
El segundo parámetro se utiliza para desplazar la barra de herramientas sin problemas.
Reemplace o envuelva el FrameLayout
dentro del android.support.design.widget.CoordinatorLayout
con un android.support.v4.widget.NestedScrollView
y que hará el trabajo automáticamente sin tener que hacer ningún otro truco ... para que se vea así :
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
android:id="@+id/appbar"
layout="@layout/appbar" />
</android.support.design.widget.CoordinatorLayout>