Programowo zwiń lub rozwiń CollapsingToolbarLayout


158

Proste pytanie, ale nie mogę znaleźć odpowiedzi. Jak mogę zwinąć lub rozwinąć CollapsingToolbarLayoutprogramowo?

zwinięty pasek narzędzi

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

rozwinięty pasek narzędzi


1
Zastanawiałem się nad tym samym. Interesujące mogłoby być również rozwinięcie paska narzędzi do pełnego ekranu po kliknięciu przez użytkownika osadzonego układu (np. Obrazu).
Moritz

Odpowiedzi:


321

Korzystając z Support Library v23, możesz zadzwonić appBarLayout.setExpanded(true/false).

Dalsze czytanie: AppBarLayout.setExpanded (boolean)


2
Ok, dziękuję za wskazówkę, ale wsparcie libs v23 jest bardzo błędne, więc nie mogę go teraz przetestować, ponieważ muszę pozostać na 22.2.1 ....
Tomas

Teraz masz 23.0.1 z kilkoma poprawkami
Mario Velasco

6
Czy można zdefiniować niestandardową animację z obsługą bibliotek 23.1.1? setExpanded (boolean, true) ma naprawdę wolną animację ...
Nifhel

Wystąpił problem polegający na tym, że mam układ ze zwijanym paskiem narzędzi i widokiem recyklingu pod nim. Podczas usuwania elementów z widoku recyklingu pasek narzędzi nie zachowywał się odpowiednio, więc rozszerzyłbym układ paska aplikacji i działał poprawnie. Skończyło się na użyciu appBarLayout.setExpanded (true, true) do animacji.
Ray Hunter,

49

Używam tego kodu do zwijania paska narzędzi. Nadal nie mogę znaleźć sposobu, aby go rozwinąć.

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);
    }
}

Edycja 1: Ta sama funkcja z ujemną prędkością Y, ale pasek narzędzi nie jest rozszerzony w 100%, a fałsz dla ostatniego parametru powinien działać

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);
    }
}

Edycja 2: ten kod załatwia sprawę za mnie

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 rozwija pasek narzędzi
  • onNestedPreScroll wyświetla zawartość w rozwiniętym pasku narzędzi

Spróbuję samodzielnie wdrożyć Behavior.


2
Edycja 1 zadziała również, jeśli ustawisz ostatni parametr onNestedFlingna false.
Ricky Lee

2
params.getBehavior () zwraca wartość null. W xml tag layout_behaviour jest ustawiany na siostrzanym NestedScrollView, a nie na AppBarLayout. Możesz mi pomóc?
User31689

Dziękuję Ci. Edycja 1 działa poprawnie, jeśli ostatni parametr jest fałszywy. :)
Sirelon

@GobletSky Napotkałem ten sam problem. Miałem NestedScrollView w moim fragmencie i próbowałem wywołać onNestedFling przed ustawieniem fragmentu. Po ustawieniu fragmentu mogłem pomyślnie wywołać metodę.
usp

@usp Właściwie mój problem był zupełnie inny (trochę niegodny błąd). Zobacz to: stackoverflow.com/questions/31067082/…
User31689

27

Możesz określić, jak bardzo się rozwija lub zwija za pomocą niestandardowego animatora. Po prostu użyj setTopAndBottomOffset(int).

Oto przykład:

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();
}

2
To jedyna odpowiedź, która faktycznie umożliwia animację do niestandardowego przesunięcia. Wielkie dzięki!
Guilherme Torres Castro,

2
appBar.setExpanded (false, true); (otwórz / zamknij, animuj) Nie musisz pisać tych wszystkich wierszy
Puni

2
do @Puni, jeśli chcesz rozwinąć / zwinąć do "niestandardowego" przesunięcia (jak przy zwijaniu wielu etapów), będziesz tego potrzebować.
曾 其 威

Jest to najlepsze rozwiązanie do animowania przesunięcia AppBar w przypadku, gdy nie chcesz pisać niestandardowego zachowania. Jedyną aktualizacją fragmentu kodu jest wywołanie valueAnimator.setIntValues ​​() z wartością początkową behawior.topAndBottomOffset zamiast 0, aby rozpocząć animację od bieżącego przesunięcia paska aplikacji.
rolka

Aby użyć niestandardowej zmiennej ( -900 )do ustawienia valueAnimator.setIntValuesLepszym rozwiązaniem jest użycie- ( appBar.getTotalScrollRange() )
Ali Rezaiyan

12

Napisałem małe rozszerzenie do AppBarLayout. Pozwala na rozwijanie i zwijanie CollapsibleToolbarLayoutzarówno z animacją, jak i bez niej. Wydaje się, że robi to całkiem dobrze.

Śmiało wypróbuj.

Po prostu użyj go zamiast swojego AppBarLayouti możesz wywołać metody odpowiedzialne za rozwijanie lub zwijanie CollapsingToolbarLayout.

Działa dokładnie tak, jak oczekiwano w moim projekcie, ale może być konieczne dostosowanie wartości fling / scroll w perform...metodach (szczególnie w performExpandingWithAnimation()), aby idealnie pasowały do ​​twojego CollapsibleToolbarLayout.


@ssdeno, przeczytaj plik Readme.md z treścią Github. Jest przestarzały od wersji 23 biblioteki pomocy technicznej. Od wersji 23 obsługi (przechodząc do AndroidX), istnieje setExpandedmetoda w AppBarLayout.
Bartek Lipiński

6

Służy mAppBarLayout.setExpanded(true)do rozwijania paska narzędzi i mAppBarLayout.setExpanded(false)zwijania paska narzędzi.

Jeśli chcesz programowo zmienić wysokość CollapsingToolbarLayout, po prostu użyj mAppBarLayout.setLayoutParams(params);

Rozszerzać:

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

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

Zawalić się:

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

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

1
To mi bardzo pomogło.
NoName

1
To jest bardzo pomocne. Dziękuję Ci!
sunlover3

5

dla tych, którzy chcą pracować z onNestedPreScroll i otrzymywać błędy jak ja. dostaję NullPointerException w onCreate bez tej linii

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

i nie działa poprawnie z tym. ale obejdę ten problem z

w onCreate:

        scrollToolbarOnDelay();

i...

    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);


        }

1

Spróbuj tego...

Rozszerzać

appBarLayout.setExpanded(true, true);

Przypomnieć sobie

appBarLayout.setExpanded(false, true);

0

Może to pomóc w rozwinięciu lub zwinięciu:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);

0

używam tego

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

0

Aby programowo rozwinąć / zwinąć AppBarLayout:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.