Ajouter des vues sous la barre d'outils dans CoordinatorLayout

176

J'ai la disposition suivante:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</android.support.design.widget.CoordinatorLayout>

J'ajoute des Fragments dans le FrameLayout, en les remplaçant. L'un de mes Fragments est une liste, qui a la disposition suivante:

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

Mon problème ici est que la barre d'outils est dessinée sur la liste . J'ai essayé de résoudre cela en enveloppant le contenu de l ' CoordinatorLayoutdans un LinearLayout, qui a résolu l'overdraw, mais de cette façon, le comportement de défilement de la barre d'application ne fonctionne plus.

Toute aide est très appréciée!

WonderCsabo
la source

Réponses:

355

Prenez l'attribut

app:layout_behavior="@string/appbar_scrolling_view_behavior"

hors RecyclerViewet le mettre sur la FrameLayoutque vous essayez de montrer sous le Toolbar.

J'ai trouvé qu'une chose importante du comportement de la vue défilante est de mettre en page le composant sous la barre d'outils. Comme le FrameLayouta un descendant qui scroll ( RecyclerView), le CoordinatorLayoutobtiendra ces événements de défilement pour déplacer le Toolbar.


Une autre chose à savoir: ce comportement de mise en page entraînera la FrameLayouttaille de la hauteur comme si le Toolbardéfilait déjà , et avec le Toolbarentièrement affiché, la vue entière est simplement poussée vers le bas de sorte que le bas de la vue soit en dessous du bas du CoordinatorLayout.

C'était une surprise pour moi. Je m'attendais à ce que la vue soit redimensionnée dynamiquement lorsque la barre d'outils défile de haut en bas. Donc, si vous avez un composant de défilement avec un composant fixe en bas de votre vue, vous ne verrez pas ce composant du bas tant que vous n'avez pas fait défiler complètement le fichier Toolbar.

Ainsi, lorsque j'ai voulu ancrer un bouton en bas de l'interface utilisateur, j'ai contourné ce problème en plaçant le bouton en bas de CoordinatorLayout( android:layout_gravity="bottom") et en ajoutant une marge inférieure égale à la hauteur du bouton à la vue sous la barre d'outils.

Kris Larson
la source
1
Merci beaucoup, cela fonctionne vraiment! Mon seul problème après cela, si la barre d'outils était déplacée, elle ne revenait pas après avoir remplacé le Fragmentcontenant par une liste par une autre Fragment. J'ai réussi à afficher manuellement la barre d'outils de cette façon.
WonderCsabo
Sensationnel. J'ai toujours pensé que la propre mise en page de Fragment remplaçait complètement l '«espace réservé» FrameLayout mais je vois que ce n'est pas du tout le cas. Merci pour cette réponse! Cela m'a beaucoup aidé.
Aspiring Dev
@Surendar D s'il vous plaît vérifier ceci si vous pouvez stackoverflow.com/questions/42968587/...
Mohamed Rihan
Agréable. Je vous remercie!
Razvan du
87

J'ai réussi à résoudre ce problème en ajoutant:

android: layout_marginTop = "? android: attr / actionBarSize"

au FrameLayout comme ceci:

 <FrameLayout
        android:id="@+id/content"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       />
Michael G
la source
9
Au lieu d'ajouter marginTop, ajoutez une application: layout_behavior = "@ string / appbar_scrolling_view_behavior"
Naveed Ahmad
3
Solution parfaite lorsque @ string / appbar_scrolling_view_behavior n'est pas disponible
Julius
Veuillez utiliserandroid:layout_marginTop="?android:attr/actionBarSize"
Martin Pfeffer
6
C'est un peu hacky, ajouter une marge de ce que la taille PEUT être (en supposant que vous aurez toujours une barre d'outils de cette taille) va casser à un moment donné
Kenny
0

Depuis Android studio 3.4, vous devez mettre cette ligne dans votre mise en page qui contient le fichier RecyclerView.

app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior"
Shashank
la source
0

Pour utiliser la barre d'outils supérieure réduite ou utiliser ScrollFlags de votre choix, nous pouvons faire de cette façon: À partir de Material Design, débarrassez-vous de FrameLayout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|enterAlways">


        <androidx.appcompat.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin">

            <ImageView
                android:id="@+id/ic_back"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_arrow_back" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="back"
                android:textSize="16sp"
                android:textStyle="bold" />

        </androidx.appcompat.widget.Toolbar>


        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/post_details_recycler"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="5dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Shiva s
la source