Hoe kan ik de Toolbar-positie die wordt bestuurd door de CoordinatorLayout resetten?

De app waar ik aan werk, bestaat uit een navigatielade die is geïmplementeerd in een activiteit. De indeling van de activiteiten is als volgt:

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

Dit is een veel voorkomend patroon, het enige dat vaak verandert, is het fragment in de containerlay-out.

Als een van de fragmenten een scrollelement heeft, zal de CoordinatorLayout tijdens het scrollen graag positievertalingen maken, inclusief de Toolbar/AppBarLayout.

Het echte probleem hier is dat wanneer het fragment wordt vervangen, de positie voor de werkbalk hetzelfde blijft, d.w.z. als de werkbalk verborgen is, blijft het zo
wat niet de bedoeling is.

Resultaat is dit:

Dit:

Na scrollen

Loopt vast:

Verander dan

Hoe kan men de Toolbar-positie voor dit geval resetten?

BEWERKEN:
Een bug is waarschijnlijk, de AppBarLayout-offset change-listener wordt alleen gebeld wanneer de app opnieuw wordt gestart (druk op de terugknop en open de app) en wordt niet meer gebeld na een intense flirt.


Antwoord 1, autoriteit 100%

Als u de schuifstatus wilt resetten, haalt u gewoon het AppBarLayout.Behavior-object

op

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

en roep de onNestedPreScrollmethode handmatig aan:

int[] consumed = new int[2];
behavior.onNestedPreScroll(coordinator, appbar, null, 0, -1000, consumed);

Als je soepel wilt resetten met een animatie, kun je in plaats daarvan proberen onNestedFlingte bellen:

behavior.onNestedFling(coordinator, appbar, null, 0, -1000, true);

Antwoord 2, autoriteit 81%

Haal eerst een AppBarLayout-referentie in uw MainActivity en gebruik vervolgens in de pauzestatus van het fragment dat wordt vervangen de onderstaande methode om de werkbalk uit te vouwen:

MainActivity.appbar.setExpanded(true,true);

En of om de werkbalk te sluiten:

MainActivity.appbar.setExpanded(false,true);

De tweede parameter wordt gebruikt om soepel door de werkbalk te scrollen.


Antwoord 3, autoriteit 27%

Update uw ondersteuningsbibliotheek naar v23, dan kunt u het volgende gebruiken:

appBarLayout.setExpanded(true/false);

public void setExpanded (boolean expanded)

Stelt in of deze AppBarLayout wordt uitgebreid of niet, en animeert als deze al is ingedeeld.

Net als bij het scrollen van AppBarLayout, gaat deze methode ervan uit dat deze lay-out een direct kind is van een CoordinatorLayout.

uitgevouwentrue als de lay-out volledig moet worden uitgevouwen, false als deze volledig moet worden samengevouwen


Antwoord 4, autoriteit 6%

@razzledazzle De AppBarLayout slaat onOffsetChangedListeners op als WeakReferences, wat betekent dat ze als afval worden verzameld wanneer dat nodig is, bijvoorbeeld wanneer je een intense flirt doet. Bekijk hier de oplossing:

https://code.google.com/p/android/ issues/detail?id=176328


Antwoord 5, autoriteit 4%

Ik gebruik deze codes voordat het fragment verandert.

scrollingElement.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
scrollingElement.dispatchNestedPreScroll(0, -Integer.MAX_VALUE, null, null);
scrollingElement.stopNestedScroll();

Antwoord 6, autoriteit 4%

Vervang of wikkel de FrameLayoutin de android.support.design.widget.CoordinatorLayoutmet een android.support.v4.widget.NestedScrollViewen dat zal het werk automatisch doen zonder andere hacks….dus het zou er als volgt uitzien:

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

Antwoord 7, autoriteit 4%

Als documentzei

AppBarLayout ondersteunt
void setExpanded (boolean uitgebreid, boolean animate);
Stelt in of deze AppBarLayout wordt uitgebreid of niet.

  • uitgevouwenboolean: waar als de lay-out volledig moet worden uitgevouwen, onwaar als deze volledig moet worden samengevouwen
  • animerenboolean: al dan niet animeren naar de nieuwe staat

Dus eerst heb je

. nodig

AppBarLayout appBarLayout = findViewById(R.id.appBarLayout);

vervolgens om de lay-out uit te breiden

appBarLayout.setExpanded(true, true); // with animation
appBarLayout.setExpanded(true, false); // without animation  

en om de lay-out samenvouwen

appBarLayout.setExpanded(false, true); // with animation
appBarLayout.setExpanded(false, false); // without animation 

Antwoord 8

// Get the reference for appbar from layout
AppBarLayout appbar = rootView.findViewById(R.id.appbar);
//boolean expanded, boolean animate
appbar.setExpanded(true, true);

Antwoord 9

Ik had een soortgelijk probleem. Mijn lay-out werd ofwel hoger geplaatst dan nodig (zoals hier), of lager, toen ik het dynamisch verkleinde. Het was een fragment dat programmatisch werd vervangen in FrameLayout.
Wat ik deed: ik begon mijn Fragment opnieuw te maken door de FrameLayout-grootte te wijzigen.

myFragment = new MyFragment();
getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_layout, myFragment)
                .commit();

Other episodes