Comment réinitialiser la position de la barre d'outils contrôlée par le CoordinatorLayout?

l'application sur laquelle je travaille se compose d'un tiroir de Navigation qui est implémenté dans une activité. La mise en page de l'activité est la suivante:

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

c'est un motif très courant, la seule chose qui change fréquemment est le Fragment à l'intérieur de la disposition du conteneur.

si un Fragment a un élément de défilement, lors du défilement, le CoordinatorLayout fera volontiers des translations de position, y compris la barre d'outils/AppBarLayout.

Le vrai problème est ici, lorsque le Fragment est remplacé, la position de la barre d'outils reste la même, c'est-à-dire que si la barre d'outils est cachée, elle le restera. ce qui n'est pas prévu.

Résultat:

Ceci:

After scroll

coince:

Then change

Comment peut-on Réinitialiser la position de la barre d'outils pour ce cas?

EDIT: Un bug est probable, L'AppBarLayout offset change listener est appelé seulement lors de la relance de l'application (appuyez sur le bouton arrière et ouvrez l'application), et cesse d'être appelé à nouveau après une passade intense.

44
demandé sur razzledazzle 2015-05-31 10:13:01

7 réponses

pour réinitialiser l'état de défilement, il suffit d'obtenir le AppBarLayout.Behavior objet

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

et appeler onNestedPreScroll méthode manuellement:

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

Si vous souhaitez réinitialiser en douceur avec une animation, vous pouvez essayer d'appeler onNestedFling au lieu de:

behavior.onNestedFling(coordinator, appbar, null, 0, -1000, true);
46
répondu MattSkala 2015-06-09 10:25:58

tout d'abord obtenir un refrence AppBarLayout dans votre MainActivity, puis dans l'état de pause du fragment qui est remplacé, utilisez la méthode ci-dessous pour étendre la barre d'outils :

MainActivity.appbar.setExpanded(true,true);

Et ou pour fermer la barre d'outils :

MainActivity.appbar.setExpanded(false,true);

Le deuxième paramètre est utilisé pour faire défiler la barre d'outils en douceur.

29
répondu Shayan Shafiee 2015-10-23 11:59:23

mise à Jour de votre soutien lib à v23 ensuite, vous pouvez utiliser:

appBarLayout.setExpanded(true/false);

public void setExpanded (boolean étendu)

détermine si cette Applbarlayout est étendue ou non, en animant si elle a déjà été mise en place.

comme pour le scrolling D'AppBarLayout, cette méthode repose sur le fait que cette mise en page est l'enfant direct d'un CoordinatorLayout.

étendu true si la mise en page doit être complètement développée, false si elle doit être totalement effondré

11
répondu Context 2015-12-03 14:57:10

@razzledazzle L'AppBarLayout stocke des listeners onoffsetchanged en tant que faibles Références, ce qui signifie qu'ils sont des déchets ramassés en cas de besoin, par exemple quand vous faites un flirt intense. Voir la solution ici:

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

3
répondu freebiefalk 2015-06-10 14:26:24

j'utilise ces codes avant les changements de fragments.

scrollingElement.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
scrollingElement.dispatchNestedPreScroll(0, -Integer.MAX_VALUE, null, null);
scrollingElement.stopNestedScroll();
2
répondu weumj 2015-06-07 16:43:22

remplacer ou envelopper le FrameLayout dans le android.support.design.widget.CoordinatorLayout avec un android.support.v4.widget.NestedScrollView et cela fera le travail automatiquement sans avoir à d'autres hacks....ainsi, il ressemblerait à ceci:

<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>
1
répondu Alécio Carvalho 2017-05-08 15:08:11

document dit

AppBarLayout supporte

void setExpanded (booléen étendu, boolean animer);

Détermine si cette Applbarlayout est étendue ou non.

  • étendu booléen: true si la mise en page doit être entièrement développé, false si elle doit être totalement effondré
  • animer booléen: s'animer ou non vers le nouvel état

donc au début vous avez besoin

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

puis développez mise en page

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

et collapse mise en page

appBarLayout.setExpanded(false, true); // with animation
appBarLayout.setExpanded(false, false); // without animation 
0
répondu hassan moradnezhad 2018-02-14 17:20:36