ViewPager dans un NestedScrollView

111

J'ai besoin de créer une interface comme Google Kiosque qui est une sorte de ViewPager (défilement horizontal) sur un en-tête réduit (défilement vertical). L'une de mes exigences est d'utiliser la nouvelle bibliothèque de support de conception présentée au Google IO 2015. ( http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

Sur la base de l'exemple créé par Chris Banes ( https://github.com/chrisbanes/cheesesquare ), j'ai atteint le point où je suis capable de faire le comportement de réduction mais avec un LinearLayout de base (sans défilement horizontal).

J'ai essayé de remplacer LinearLayout par un ViewPager et j'ai eu un écran vide. J'ai joué avec: la largeur, le poids et toutes sortes de groupes de vues mais .... toujours un écran vide. Il semble que ViewPager et NestedScrollView ne s'aiment pas.

J'ai essayé une solution de contournement en utilisant un HorizontalScrollView: cela fonctionne mais je perds l'avantage de la fonctionnalité PagerTitleStrip et la mise au point sur un seul panneau (je peux arrêter horizontalement entre 2 panneaux).

Maintenant je n'ai plus d'idées, si quelqu'un peut m'amener à une solution ...

Merci

Voici mon dernier fichier de mise en page:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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:layout_width="match_parent"
        android:layout_height="@dimen/header_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <include
                layout="@layout/part_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/activity_main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/activity_main_nestedscrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.view.ViewPager
            android:id="@+id/activity_main_viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFA0"/>


    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Kyso84
la source
Avez-vous essayé d'emballer votre ViewPagerintérieur LinearLayout? Juste curieux de savoir si cela rendrait le ViewPagercorrectement.
CzarMatt
Oui j'ai essayé mais toujours le même résultat. J'ai fait de nombreux tests avec de nombreux composants mais le ViewPager n'est jamais rendu dans un NestedScrollView quelle que soit la hiérarchie
Kyso84
Je viens de créer une application de test avec un ViewPagerintérieur NestedScrollViewcomme seules mises en page - cela semblait fonctionner correctement. J'ai également pu DrawerLayoutréussir un . Peut-être y a-t-il un autre aspect de votre code qui empêche la fonctionnalité souhaitée. Vous souhaitez partager davantage votre source?
CzarMatt
Wow, vous pouvez donc balayer vers la gauche / droite et le haut / bas? J'utilise simplement un FragmentPagerAdapter pour afficher des fragments dans mon pager. Pouvez-vous partager votre exemple de code à la place?
Kyso84
J'ai collé un exemple de mise en page simple ici: pastebin.com/jXPw6mtf Edit: Vous pouvez charger le fragment de votre choix dans le fichier ViewPager. Je suis capable de faire défiler les vues de haut en bas, ainsi que de faire défiler la ViewPagergauche / droite.
CzarMatt

Réponses:

128

Je rencontre ce problème, je le résous en setFillViewport (true)

<android.support.v4.widget.NestedScrollView
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:id="@+id/nest_scrollview"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="mio.kon.yyb.nestedscrollviewbug.ScrollingActivity"
tools:showIn="@layout/activity_scrolling">


    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

en activité

  NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nest_scrollview);
    scrollView.setFillViewport (true);

entrez la description de l'image ici

mio4kon
la source
31
Notez que cela peut également être défini en XML, il suffit de l'ajouter android:fillViewport="true"à l' NestedScrollViewobjet. La documentation décrit cet attribut comme Defines whether the scrollview should stretch its content to fill the viewport..
Krøllebølle
7
Cela ne résout pas le problème de défilement dans les fragments d'espace réservé
Atieh
3
Merci! Je me suis assis android:fillViewport="true"sur NestedScrollViewet à l'intérieur du fragmentj'ai un listViewendroit où j'étais assis android:nestedScrollingEnabled="true".. Correction du problème de défilement
radubogdan
@ Krøllebølle NestedScrollView n'a pas cet attribut, vous devez le définir par programme.
Ouais ça marche pour moi. J'ai un problème lorsque j'ai défini la hauteur de viewpager sur match_parent dans NestedScrollView, il n'affichait pas les vues.
Waheed Nazir
71

D'accord, j'ai fait une petite démo avec ViewPageret NestedScrollView. Le problème auquel j'ai été confronté concernait la hauteur ViewPageret le ListView. Donc , je l' ai fait une petite modification sur ListViewet ViewPager'smesure de la hauteur.

Si quelqu'un souhaite consulter le code, voici le lien: https://github.com/TheLittleNaruto/SupportDesignExample/

Production:

entrez la description de l'image ici

TheLittleNaruto
la source
ne fonctionne pas, si le fragment n'a pas de listview, même forlistview fonctionne si le nombre d'éléments est le même pour tous les fragments.
Pankaj Arora
3
Je suis peut-être un peu en retard à la fête, mais je travaillais là-dessus aujourd'hui, et je l'ai (principalement) en train de travailler avec l'ajout de l'application: layout_behavior = "@ string / appbar_scrolling_view_behavior" à la fois sur le ViewPager et sur la vue parent de chaque fragment.
Graeme
1
Nul doute que cela fonctionne, mais cela ne complique-t-il pas trop le problème? J'ai résolu ce problème en me débarrassant de NestedScrollViewet en utilisant un à la LinearLayoutplace. Quels seraient les avantages d'avoir un NestedScrollViewover a LinearLayoutsi tout le but est de faire défiler le contenu dans le ViewPager? Corrigez-moi si j'ai tort, s'il-vous plait. : x Merci
Crampes
1
Merci beaucoup! J'étais sur le point de m'arracher les cheveux, et votre WrapContentHeightViewPager fonctionne comme un charme. Je t'en dois une!
Mavamaarten
1
Solution parfaite. Merci. Cela a fonctionné pour moi .. :)
Mrunal
42

Ajoutez android:fillViewport="true"votre NestedScrollView. période.

Sujit Yadav
la source
3
cela résout le problème mais la hauteur du viewpager sera le parent correspondant (cela prend toute la hauteur de la page).
Manukumar
27

Au lieu de placer ViewPager à l'intérieur du NestedScrollView, faites-le dans l'autre sens.

Placez le NestedScrollView dans les vues enfants à l'intérieur du ViewPager, qui est essentiellement la disposition du fragment. Il est également très probable que vous n'ayez même pas besoin d'utiliser NestedScrollView si la disposition de la liste de votre Fragment est très simple.

Exemples de dispositions

Disposition de l'activité:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="@dimen/app_bar_height"
                android:scaleType="centerCrop"
                android:src="@drawable/my_bg"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.8"
                app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

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

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.design.widget.TabLayout
            android:id="@+id/content_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>

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

Si vous n'avez pas besoin de TabLayout, vous pouvez abandonner LinearLayout et rendre ViewPager autonome. Mais assurez-vous d'utiliserapp:layout_behavior="@string/appbar_scrolling_view_behavior" dans les attributs ViewPager.

Disposition du fragment simple:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Disposition du fragment complexe:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World"/>
    </RelativeLayout>
</android.support.v4.widget.NestedScrollView>

Exemple d'application: CollapsingToolbarPoc

entrez la description de l'image ici

Ino
la source
C'est celui qui l'a fait pour moi. Merci!
rjr-apps
Hey Ino, cela semble fonctionner mais quand j'ajoute une autre vue au-dessus du TabLayout, sa rupture. Pouvez-vous nous aider?
hushed_voice
Vous avez sauvé mes jours. :)
androidXP
20

Eu les mêmes problèmes.

Lorsque vous placez NestedScrollView autour du ViewPager, cela ne fonctionnerait pas.

Ce qui a fonctionné, c'est de placer le NestedScrollView dans la mise en page du fragment que je charge dans le ViewPager.

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@id/fragment_detail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            android:orientation="vertical">
    ...Content...
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

ThemBones
la source
Cela fonctionne-t-il si le contenu était une mise en page de coordination avec un autre NestedScrollView? Et le parent CoordinatorLayout écoute-t-il les événements de défilement là-bas?
Atieh le
Ce travail pour moi. J'ajoute le NestedScrollView à chaque élément de mon ViewPager au lieu du ViewPager. Merci.
jerogaren
J'ai swipefreshlayout en fragment, selon votre solution, j'ai mis NestedScrollview en fragment, au-dessus de swipeRefreshLayout .. alors les données ne sont pas chargées. Cela n'a pas fonctionné.
Palak Darji
16

vous pouvez essayer comme ceci, le viewpager fonctionne bien, mais la hauteur du viewpager est fixe.

je suis toujours en train de trouver la meilleure solution ..., alors s'il vous plaît laissez-moi savoir que tout point peut le faire mieux, merci

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="800dp"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>
Paul
la source
Avez-vous essayé de l'encapsuler dans un "android.support.design.widget.CoordinatorLayout" et une barre d'outils de réduction?
Kyso84
Vos solutions semblent prouver que le problème est dans la hauteur. Vous avez encore trouvé des améliorations @Paul?
jasxir
3
Celui-ci a fonctionné pour moi, mais j'ai également dû appeler setFillViewport (true) sur le nestedview.
larrytech
12

J'ai eu le même problème et je l'ai juste corrigé avec quelques modifications. ViewPagerne fonctionne pas dans le NestedScrollView. Mettez simplement votre ViewPagercomme un enfant direct de votre CoordinatorLayout. Ensuite, le contenu de chaque fragment de ViewPager doit être inclus dans NestedScrollView. C'est tout.

BST Kaal
la source
même si le contenu était une mise en page de coordination avec un autre NestedScrollView?
Atieh le
1
Les données de la vue de liste de fragments ne sont pas chargées de cette façon!
Palak Darji
5

Vous n'avez pas besoin d'utiliser NestedScrollView pour avoir les effets de parallaxe. essayez quelque chose comme ça:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true">

        <android.support.v7.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways"/>

        <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/my_tab_layout"
            android:fillViewport="false"
            app:tabMode="fixed"/>
     </android.support.design.widget.AppBarLayout>

            <android.support.v4.view.ViewPager
                android:id="@+id/my_view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</android.support.design.widget.CoordinatorLayout>
Pedro Henrique
la source
3
Cela fonctionnera, tant que tous vos ViewPagerfragments sont de l'éther RecyclerView, ou NestedScrollView. S'ils ne le sont pas (par exemple ListView), une solution de contournement pour Lollipop et les listView.setNestedScrollingEnabled(true)
versions ultérieures
enfin quelque chose qui fonctionne sans ajouter de conteneur de défilement supplémentaire! Btw, vous pouvez définir ce setNestedScrollingEnabled (true) en xml aussi: android: nestedScrollingEnabled = "true"
Analizer
1
Si j'exécute mon application, réduis la barre d'outils dans un onglet, change d'onglet, puis tire la barre d'outils vers le bas, elle est vide. Vous devez changer d'onglet alors qu'il est dans un état non réduit pour le récupérer. Si proche, mais si loin :(
moi--
4

J'avais une mise en page avec une barre d'outils d'application avec NestedScrollView en dessous, puis à l'intérieur de la barre d'outils imbriquée se trouvait un LinearLayout, sous le LinearLayout se trouvait un pager de vue. L'idée était que le LinearLayout à l'intérieur du NestedScrollView a été corrigé - vous pouvez glisser à gauche / droite entre les vues du pagineur de vue, mais ce contenu ne se déplace pas, du moins horizontalement . Vous devriez toujours pouvoir faire défiler tout le contenu verticalement grâce à la vue de défilement imbriquée. C'était l'idée. J'ai donc défini la hauteur imbriquée de NestedScrollView sur match_parent, remplir la fenêtre, puis toutes les mises en page enfants / ViewPager sur wrap_content.

Dans ma tête c'était vrai. Mais cela n'a pas fonctionné - ViewPager m'a permis d'aller à gauche / droite, mais pas de défilement vertical, que le contenu de la page du visualiseur soit poussé en dessous du bas de l'écran actuel ou non. Il s'avère que c'était essentiellement parce que le ViewPager ne respecte pas wrap_content sur ses différentes pages.

J'ai contourné cela en sous-classant le ViewPager pour le faire changer de hauteur en fonction de l'élément actuellement sélectionné, en le forçant à se comporter comme layout_height = "wrap_content":

public class ContentWrappingViewPager extends ViewPager {

    public ContentWrappingViewPager(Context context) {
        super(context);
    }

    public ContentWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

La solution s'est inspirée de cette réponse . A travaillé pour moi!

Breeno
la source
mais la vue de défilement défile automatiquement vers le haut? Comment régler ceci ?
Vivek Kumar
4

il suffit de mettre cette ligne dans NestedScrollView

android:fillViewport="true"
gholam
la source
Des tonnes de remerciements. Que faire si je veux faire défiler en touchant directement CollapsingToolbarLayout?
Pratik Saluja
3

J'ai supprimé NestedScrollView de la mise en page principale et inséré en tant que parent dans toutes mes mises en page Fragment qui étaient censées se charger dans ViewPager, ce problème a été résolu pour moi.

Riddhish Ojha
la source
3

Utilisez la classe personnalisée ci-dessous pour résoudre votre problème. N'oubliez pas d'appeler la méthode onRefresh () sur pagechangelistener.

public class ContentWrappingViewPager extends ViewPager
{
    private int width = 0;
    public ContentWrappingViewPager(Context context) {
        super(context);
    }

    public ContentWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int height = 0;
        width = widthMeasureSpec;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void onRefresh()
    {
        try {
            int height = 0;
            if (getChildCount() > getCurrentItem()) {
                View child = getChildAt(getCurrentItem());
                child.measure(width, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                int h = child.getMeasuredHeight();
                if(h > height) height = h;
            }

            int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            ViewGroup.LayoutParams layoutParams = this.getLayoutParams();
            layoutParams.height = heightMeasureSpec;
            this.setLayoutParams(layoutParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Kuldeep Sakhiya
la source
2

J'avais un problème similaire (mais sans CollapsingToolbarLayout, juste un simple Toolbar+ TabLayoutdans le AppBarLayout). Je voulais que la barre d'outils défile hors de vue lors du défilement du contenu d'un ViewPagerdans leNestedScrollView .

Ma mise en page ressemblait à ceci:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <android.support.v4.widget.NestedScrollView
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                android:layout_gravity="fill_vertical"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </android.support.v4.widget.NestedScrollView>

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

Cette mise en page ne fonctionnait pas comme prévu, mais je l'ai résolue en me débarrassant simplement de NestedScrollViewet en utilisant un LinearLayout. Cela a fonctionné pour moi tout de suite sur la bibliothèque de support Android v23.1.0. Voici comment la mise en page s'est terminée:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <LinearLayout
            android:orientation="vertical"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="4dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </LinearLayout>

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

PS: Il s'agissait en fait de deux fichiers de mise en page dans mon projet. Je les ai copiés et collés ici et j'ai essayé de les structurer comme cela ressemblerait dans un seul fichier. Je suis désolé si je me suis trompé lors du copier-coller, mais s'il vous plaît laissez-moi savoir si c'est le cas afin que je puisse le réparer.

Crampes
la source
1

Les éléments suivants doivent garantir la bonne hauteur du téléavertisseur. Le fragment est le premier fragment fourni par le pager de vue.

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <fragment
            class="com.mydomain.MyViewPagerFragment"
            android:id="@+id/myFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
Jon
la source
1

J'ai le même souhait, nid a l' ViewPagerintérieur a NestedScrollView. Mais cela ne fonctionne pas non plus pour moi. Dans mon cas, le ViewPagerest à l'intérieur d'unFragment afin que je puisse changer de contenu en fonction des interactions avec le tiroir. Bien sûr, AppBar, collapse, etc. et toutes les nouvelles fonctionnalités de la bibliothèque de support doivent fonctionner.

Si un utilisateur fait défiler verticalement une page dans le pager, je veux que les autres pages défilent de la même manière, pour donner à l'utilisateur l'impression générale que le pager lui-même a défilé.

Ce que j'ai fait, ce qui fonctionne, c'est que je n'intègre plus l' ViewPagerintérieur a NestedScrollView, à la place, j'intègre le contenu des fragments contenus dans un fichier NestedScrollView.

Ensuite, en cas de défilement dans un fragment, j'informe le conteneur de la nouvelle position de défilement, qui le stocke.

Enfin, lors d'un balayage vers la gauche ou vers la droite détecté depuis le pager (en utilisant la addOnPageChangeListenerrecherche des états de glissement), j'informe le fragment cible gauche ou droit où il doit défiler (en fonction de la connaissance du conteneur) pour être aligné à partir du fragment dont je viens.

François Perret
la source
Donc, essentiellement, vous avez écrit votre propre implémentation ViewPager? Seriez-vous capable de partager du code à ce sujet?
joseph
J'ai fait quelque chose de similaire (si je comprends bien), qui consiste à faire une mise en page linéaire dans votre mise en page de coordinateur, qui contient le tablayout (si nécessaire) et le viewpager, au lieu d'un scrollview imbriqué. Les fragments eux-mêmes ont alors le scrollview imbriqué comme élément racine. Cela fonctionne pour moi, mais je préférerais avoir juste une vue de défilement imbriquée au lieu de la répéter dans chaque fragment.
Chris
0

Je connais une solution de travail: vous utilisez Activity, avec CoordinatorLayout et utilisez FrameLayout, container. Ensuite. utilisez le gestionnaire de fragments pour mettre le fragment dans le conteneur. Par exemple mon code:

<android.support.design.widget.CoordinatorLayout 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:orientation="vertical">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        app:layout_scrollFlags="scroll|enterAlways"
        android:layout_height="@dimen/toolbar_height"
        android:background="?attr/colorPrimary"
        android:gravity="center">

    </android.support.v7.widget.Toolbar>


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

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

</FrameLayout>

Et Fragment:

<LinearLayout 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:orientation="vertical"
tools:context="com.improvemdia.inmyroom.MainFragment">

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Ensuite, utilisez FragmentManager

getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MainFragment())
            .commit();
rz0
la source
Je pense que la LinearLayoutmise en page du fragment est inutile ici. Voir ma réponse, j'ai utilisé a LinearLayoutau lieu de a FrameLayoutdans la mise en page de mon activité, et la racine de mon fragment est un ViewPager (pas de mise en page enveloppante).
Crampes
0

Après avoir passé des heures à essayer toutes les suggestions ci-dessus, je l'ai finalement fait fonctionner. La clé est de mettre à l' NestedScrollViewintérieur PageViewer, et un ensemble layout_behaviorà '@string/appbar_scrolling_view_behavior'des DEUX vues. La mise en page finale est comme

<CoordinatorLayout>
    <ViewPager app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <NestedScrollView fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <Content>...</Content>
        </NestedScrollView>
    </ViewPager>
    <AppBarLayout>...</AppBarLayout>
</CoordinatorLayout>
Tranquillisant
la source
0

vous venez de supprimer le NestedScrollView sur votre xml et ajoutez ce code sur votre classe

yourGridView.setNestedScrollingEnabled(true);

Rivaldy Firmansyah
la source
0

En fait, NestedScrollView n'a pas besoin d'être le frère direct de CollapsingToolbarLayout dans CoordinatorLayout. J'ai réalisé quelque chose de vraiment bizzare. L'appbar_scrolling_view_behavior fonctionne dans 2 fragments imbriqués.

Ma disposition d'activité:

<android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout>

            <android.support.design.widget.CollapsingToolbarLayout>

                <include
                    layout="@layout/toolbar"/>

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

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

    <FrameLayout
        android:id="@+id/container"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

Dans le frameLayout "container", j'ai gonflé ce fragment:

<android.support.constraint.ConstraintLayout>

    ... some content ...

    <android.support.v4.view.ViewPager/>

    ...

</android.support.constraint.ConstraintLayout>

Et les fragments à l'intérieur de ce ViewPager ressemblent à ceci:

<RelativeLayout>

    <android.support.v7.widget.RecyclerView/>

    ....

</RelativeLayout>

Le fait que NestedScrollView puisse être si profond dans la hiérarchie des enfants de CoordinatorLayout et les comportements de défilement toujours fonctionne m'a surpris.

Alex Mensak
la source