CollapsingToolbarLayout programmgesteuert reduzieren oder erweitern

158

Einfache Frage, aber ich kann keine Antwort finden. Wie kann ich das CollapsingToolbarLayoutprogrammgesteuert reduzieren oder erweitern ?

reduzierte Symbolleiste

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

erweiterte Symbolleiste

Tomas
quelle
1
Ich habe mich das Gleiche gefragt. Es könnte auch interessant sein, die Symbolleiste auf Vollbild zu erweitern, sobald ein Benutzer auf das eingebettete Layout (z. B. Bild) klickt.
Moritz

Antworten:

321

Mit Support Library v23 können Sie anrufen appBarLayout.setExpanded(true/false).

Weiterführende Literatur: AppBarLayout.setExpanded (boolean)

jaxvy
quelle
2
Ok, danke für den Tipp, aber die Unterstützung von libs v23 ist sehr fehlerhaft, daher kann ich sie jetzt nicht testen, da ich am 22.2.1 bleiben muss ....
Tomas
Jetzt haben Sie 23.0.1 mit einigen Korrekturen
Mario Velasco
6
Ist es möglich, eine benutzerdefinierte Animation mit den Unterstützungsbibliotheken 23.1.1 zu definieren? setExpanded (boolean, true) hat eine sehr langsame Animation ...
Nifhel
Ich hatte ein Problem, bei dem ich ein Layout mit einer zusammenklappbaren Symbolleiste und einer Recycling-Ansicht darunter habe. Beim Löschen von Elementen aus der Recycling-Ansicht hat sich die Symbolleiste nicht richtig verhalten, daher habe ich das Layout der App-Leiste erweitert und es hat ordnungsgemäß funktioniert. Am Ende habe ich appBarLayout.setExpanded (true, true) für die Animation verwendet.
Ray Hunter
49

Ich benutze diesen Code zum Reduzieren der Symbolleiste. Ich kann immer noch keinen Weg finden, es zu erweitern.

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

Bearbeiten 1: Dieselbe Funktion mit negativer GeschwindigkeitY, aber die Symbolleiste wird nicht um 100% erweitert und false für den letzten Parameter sollte funktionieren

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

Edit 2: Dieser Code macht den Trick für mich

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 erweitert die Symbolleiste
  • onNestedPreScroll zeigt den Inhalt in der erweiterten Symbolleiste an

Ich werde versuchen, das Verhalten selbst umzusetzen.

Tuấn Trần Anh
quelle
2
Bearbeiten 1 funktioniert auch, wenn Sie den letzten Parameter von onNestedFlingauf setzen false.
Ricky Lee
2
params.getBehavior () gibt null zurück. In XML wird das Tag layout_behaviour für das Geschwister NestedScrollView festgelegt, nicht für das AppBarLayout. Können Sie mir helfen?
User31689
Danke dir. Bearbeiten 1 funktioniert ordnungsgemäß, wenn der letzte Parameter falsch ist. :)
Sirelon
@GobletSky Ich hatte das gleiche Problem. Ich hatte NestedScrollView in meinem Fragment und versuchte aufzurufen, onNestedFling bevor ich das Fragment festlegte . Nachdem ich das Fragment gesetzt hatte, konnte ich die Methode erfolgreich aufrufen.
Usp
@usp Eigentlich war mein Problem ganz anders (etwas noobischer Fehler). Siehe dies: stackoverflow.com/questions/31067082/…
User31689
27

Sie können mit Ihrem benutzerdefinierten Animator festlegen, um wie viel es erweitert oder reduziert wird. Verwenden Sie einfach die setTopAndBottomOffset(int).

Hier ist ein Beispiel:

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
quelle
2
Dies ist die einzige Antwort, mit der Sie tatsächlich zu einem benutzerdefinierten Offset animieren können. Danke vielmals!
Guilherme Torres Castro
2
appBar.setExpanded (false, true); (öffnen / schließen, animieren) Sie müssen nicht alle diese Zeilen schreiben
Puni
2
Wenn Sie bei @Puni auf einen "benutzerdefinierten" Versatz erweitern / reduzieren möchten (wie beim Reduzieren mehrerer Stufen), benötigen Sie dies.
曾 其 威
Dies ist die beste Lösung, um den AppBar-Offset zu animieren, falls Sie kein benutzerdefiniertes Verhalten schreiben möchten. Die einzige Aktualisierung des Code-Snippets besteht darin, valueAnimator.setIntValues ​​() mit dem Startwert behaviour.topAndBottomOffset anstelle von 0 aufzurufen, um die Animation vom aktuellen Appbar-Offset aus zu starten.
Rolle
So verwenden Sie eine benutzerdefinierte Variable ( -900 )zum valueAnimator.setIntValues- ( appBar.getTotalScrollRange() )
Festlegen
12

Ich habe eine kleine Erweiterung an geschrieben AppBarLayout. Es ermöglicht das Erweitern und Reduzieren von CollapsibleToolbarLayoutsowohl mit als auch ohne Animation. Es scheint ganz richtig zu sein.

Probieren Sie es einfach aus.

Verwenden Sie es einfach anstelle von Ihrem AppBarLayout, und Sie können Methoden aufrufen, die für das Erweitern oder Reduzieren des CollapsingToolbarLayout.

Es funktioniert genau wie erwartet in meinem Projekt, aber möglicherweise müssen Sie die Fling- / Scroll-Werte in den perform...Methoden (insbesondere in performExpandingWithAnimation()) anpassen, um sie perfekt an Ihre anzupassen CollapsibleToolbarLayout.

Bartek Lipinski
quelle
@ssdeno bitte lesen Sie die Readme.md des Github-Kerns. Es ist seit Version 23 der Support-Bibliothek veraltet. Seit der Version 23 des Supports (weiter mit AndroidX) gibt es eine setExpandedMethode in der AppBarLayout.
Bartek Lipinski
6

Verwenden Sie mAppBarLayout.setExpanded(true)diese Option, um die Symbolleiste zu erweitern und die Symbolleiste mAppBarLayout.setExpanded(false)zu reduzieren.

Wenn Sie die Höhe von CollapsingToolbarLayout programmgesteuert ändern möchten, verwenden Sie einfach mAppBarLayout.setLayoutParams(params);

Erweitern:

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

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

Zusammenbruch:

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

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(false);
Ferdous Ahamed
quelle
1
Das hat mir sehr geholfen.
NoName
1
Das ist so hilfreich. Danke dir!
sunlover3
5

für diejenigen, die mit onNestedPreScroll arbeiten und Fehler wie ich erhalten möchten. Ich bekomme NullPointerException in onCreate ohne diese Zeile

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

und funktioniert damit nicht richtig. aber ich arbeite mit diesem Problem um

in onCreate:

        scrollToolbarOnDelay();

und...

    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
quelle
1

Versuche dies...

Erweitern

appBarLayout.setExpanded(true, true);

Zurückrufen

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

Dies kann helfen, sich auszudehnen oder zusammenzubrechen:

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

Ich habe dies verwendet

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

So programmieren / reduzieren Sie AppBarLayout programmgesteuert:

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