Colapsar o expandir mediante programación CollapsingToolbarLayout

159

Pregunta simple, pero no puedo encontrar una respuesta. ¿Cómo puedo colapsar o expandir CollapsingToolbarLayoutprogramáticamente?

barra de herramientas contraída

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

barra de herramientas expandida

Tomás
fuente
1
Me preguntaba lo mismo. También podría ser interesante expandir la barra de herramientas a pantalla completa una vez que un usuario hace clic en el diseño incrustado (por ejemplo, imagen).
Moritz

Respuestas:

322

Usando Support Library v23, puede llamar appBarLayout.setExpanded(true/false).

Lectura adicional: AppBarLayout.setExpanded (boolean)

jaxvy
fuente
2
Ok, gracias por el consejo, pero las libs v23 de soporte son muy defectuosas, así que no puedo probarlo ahora, porque necesito quedarme en 22.2.1 ...
Tomás
Ahora tienes 23.0.1 con algunas correcciones
Mario Velasco
66
¿Es posible definir una animación personalizada con libs de soporte 23.1.1? setExpanded (boolean, true) tiene una animación realmente lenta ...
Nifhel
Tuve un problema en el que tengo un diseño con una barra de herramientas plegable y una vista de reciclador debajo. Al eliminar elementos de la vista del reciclador, la barra de herramientas no se comportó adecuadamente, por lo que expandiría el diseño de la barra de la aplicación y funcionó correctamente. Terminé usando appBarLayout.setExpanded (verdadero, verdadero) para la animación.
Ray Hunter
48

Yo uso este código para colapsar la barra de herramientas. Todavía no puedo encontrar una manera de expandirlo.

public void collapseToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, 10000, true);
    }
}

Edición 1: la misma función con velocidad negativa Y pero la barra de herramientas no está expandida al 100% y falso para el último parámetro debería funcionar

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, -10000, false);
    }
}

Edición 2: este código hace el truco para mí

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.setTopAndBottomOffset(0);
        behavior.onNestedPreScroll(rootLayout, appbarLayout, null, 0, 1, new int[2]);
    }
}
  • setTopAndBottomOffset expande la barra de herramientas
  • onNestedPreScroll muestra el contenido dentro de la barra de herramientas expandida

Intentaré implementar el comportamiento por mí mismo.

Tuấn Trần Anh
fuente
2
Editar 1 también funcionará si establece el último parámetro de onNestedFlinga false.
Ricky Lee
2
params.getBehavior () está devolviendo nulo. En xml, la etiqueta layout_behaviour se establece en el hermano NestedScrollView, no en AppBarLayout. ¿Me puedes ayudar?
Usuario31689
Gracias. Editar 1 funciona correctamente, si el último parámetro es falso. :)
Sirelon
@GobletSky Me enfrenté al mismo problema. Tenía NestedScrollView en mi fragmento e intenté llamar onNestedFling antes de configurar el fragmento. Después de configurar el fragmento, podría llamar al método con éxito.
usp
@usp En realidad, mi problema era completamente diferente (error algo novato). Vea esto: stackoverflow.com/questions/31067082/…
User31689
27

Puede definir cuánto se expande o colapsa con su animador personalizado. Solo usa el setTopAndBottomOffset(int).

Aquí hay un ejemplo:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBar.getLayoutParams();
final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
if (behavior != null) {
    ValueAnimator valueAnimator = ValueAnimator.ofInt();
    valueAnimator.setInterpolator(new DecelerateInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            behavior.setTopAndBottomOffset((Integer) animation.getAnimatedValue());
            appBar.requestLayout();
        }
    });
    valueAnimator.setIntValues(0, -900);
    valueAnimator.setDuration(400);
    valueAnimator.start();
}
Gerhard
fuente
2
Esta es la única respuesta que realmente te permite animar a un desplazamiento personalizado. ¡Muchas gracias!
Guilherme Torres Castro
2
appBar.setExpanded (falso, verdadero); (abrir / cerrar, animar) No necesita escribir todas esas líneas
Puni
2
a @Puni, si desea expandir / contraer a un desplazamiento "personalizado" (como colapsar varias etapas), necesitará esto.
曾 其 威
Esta es la mejor solución para animar el desplazamiento de AppBar en caso de que no desee escribir un comportamiento personalizado. La única actualización del fragmento de código es llamar a valueAnimator.setIntValues ​​() con el valor inicial de behaviour.topAndBottomOffset en lugar de 0 para iniciar la animación desde el desplazamiento actual de la barra de aplicaciones.
carrete
Para usar una variable personalizada ( -900 )para establecer valueAnimator.setIntValuesLa mejor solución es usar- ( appBar.getTotalScrollRange() )
Ali Rezaiyan
12

He escrito una pequeña extensión para AppBarLayout. Permite la expansión y el colapso de CollapsibleToolbarLayoutambos con y sin animación. Parece estar haciéndolo bien.

Siéntase libre de probarlo.

Simplemente utilícelo en lugar de su AppBarLayout, y puede llamar a los métodos responsables de expandir o colapsar el CollapsingToolbarLayout.

Funciona exactamente como se esperaba en mi proyecto, pero es posible que deba ajustar los valores de lanzamiento / desplazamiento en los perform...métodos (especialmente en performExpandingWithAnimation()) para que se adapten perfectamente a su CollapsibleToolbarLayout.

Bartek Lipinski
fuente
@ssdeno por favor lea el Readme.md de la esencia de Github. Está en desuso desde la v23 de la biblioteca de soporte. Desde la v23 de Soporte (pasando a AndroidX), hay un setExpandedmétodo en el AppBarLayout.
Bartek Lipinski
6

Use mAppBarLayout.setExpanded(true)para expandir la barra de herramientas y usemAppBarLayout.setExpanded(false) para contraer la Barra de herramientas.

Si desea cambiar la altura de CollapsingToolbarLayout mediante programación, simplemente use mAppBarLayout.setLayoutParams(params);

Expandir:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*200; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(true);

Colapso:

CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*80; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(false);
Ferdous Ahamed
fuente
1
Esto me ayudó mucho.
NoName
1
Esto es muy útil ¡Gracias!
sunlover3
5

para aquellos que quieren trabajar con onNestedPreScroll y obtener un error como yo. me sale NullPointerException en onCreate sin esta línea

    CoordinatorLayout coordinator =(CoordinatorLayout)findViewById(R.id.tab_maincontent);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
    //below line
    params.setBehavior(new AppBarLayout.Behavior() {});

y no funciona correctamente con esto. pero evito este problema con

en onCreate:

        scrollToolbarOnDelay();

y...

    public void scrollToolbarOnDelay() {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.tab_appbar);
                    CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.tab_maincontent);
                    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
                    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
         if(behavior!=null)
                    behavior.onNestedPreScroll(coordinator, appBarLayout, null, 0, 100, new int[]{0, 0});
         else
            scrollToolbarOnDelay()
                }
            }, 100);


        }
Sepehr Nozaryian
fuente
1

Prueba esto...

Expandir

appBarLayout.setExpanded(true, true);

Para recordar

appBarLayout.setExpanded(false, true);
Victor Sam VS
fuente
0

Esto puede ayudar a expandir o colapsar:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);
LIEN ROHIT
fuente
0

he usado esto

 private fun collapseAppbar() {
        scrollView.postDelayed(Runnable {
            scrollView?.smoothScrollTo(50, 50)
        }, 400)
    }
denizs
fuente
0

Para expandir / contraer AppBarLayout mediante programación:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
avisper
fuente