web-dev-qa-db-fra.com

Android CoordinatorLayout + AppbarLayout + Viewpager défilant toujours

J'ai une disposition classique avec une barre d'outils en haut, un TabLayout en dessous et un onglet de commutation ViewPager à partir du TabLayout. Lorsque le contenu du ViewPager peut défiler, la barre d'outils doit défiler hors de vue, et le TabLayout doit suivre et coller lorsqu'il atteint le sommet.

Tout cela est bon dans mon code actuel, sauf que la barre d'outils est toujours défilable, quelle que soit la taille du contenu de ViewPager. Voir mon code ci-dessous. Des idées brillantes sur la façon de résoudre ce problème?

<?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:orientation="vertical">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/app_bar_layout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="@color/primary"
        Android:orientation="vertical">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:theme="@style/AppTheme.ToolBar"
            app:layout_scrollFlags="scroll|enterAlways" />

        <Android.support.design.widget.TabLayout
            Android:id="@+id/tabs"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="?attr/colorPrimary"
            Android:scrollbars="horizontal"
            app:tabIndicatorColor="@color/black_text" />

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

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

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

MODIFIER:

Je peux voir que la hauteur du viewPager est la même que la hauteur de la vue racine entière. Cela peut être intentionnel, car appbar_scrolling_view_behavior semble ajouter un décalage supérieur et inférieur. Cela semble cependant étrange, car cela entraînera toujours le défilement de la barre d'outils et de la barre d'onglets.

27
Kenneth

Basé sur d'autres exemples, mon propre code et le code source (quelque peu désordonné) de appbar_scrolling_view_behavior:

        public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
            View dependency) {
        final CoordinatorLayout.Behavior behavior =
                ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
        if (behavior instanceof Behavior) {
            // Offset the child so that it is below the app-bar (with any overlap)

            final int appBarOffset = ((Behavior) behavior)
                    .getTopBottomOffsetForScrollingSibling();
            final int expandedMax = dependency.getHeight() - mOverlayTop;
            final int collapsedMin = parent.getHeight() - child.getHeight();

            if (mOverlayTop != 0 && dependency instanceof AppBarLayout) {
                // If we have an overlap top, and the dependency is an AppBarLayout, we control
                // the offset ourselves based on the appbar's scroll progress. This is so that
                // the scroll happens sequentially rather than linearly
                final int scrollRange = ((AppBarLayout) dependency).getTotalScrollRange();
                setTopAndBottomOffset(AnimationUtils.lerp(expandedMax, collapsedMin,
                        Math.abs(appBarOffset) / (float) scrollRange));
            } else {
                setTopAndBottomOffset(dependency.getHeight() - mOverlayTop + appBarOffset);
            }
        }
        return false;
    }

Je lis ceci d'une manière expliquant le problème, car c'est un comportement attendu avec ce code.

Je pense que nous devons écrire notre propre comportement de défilement, spécialement pour le RecyclerView,

0
Kenneth

J'ai résolu le problème, essayé l'exemple de modèle Google et découvert que

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

la ligne doit être ajoutée dans les propriétés du pager de vue xml. Cela a résolu mon problème.

6
Mert

Je vous ai suggéré d'essayer this sample.

c'est une mise en page comme votre mise en page dans l'exemple.

<Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/main_content"
    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.Dark.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:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

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

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

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

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="end|bottom"
        Android:layout_margin="@dimen/fab_margin"
        Android:src="@drawable/ic_done" />

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

utiliser ListView comme données pour ViewPager? Si oui, vous avez besoin de listView.setNestedScrollingEnabled(true);

2
a442509097

Essayez d'ajouter ces attributs sur TabLayout:

 app:layout_collapseMode="pin"
 app:tabMode="fixed"

Et cela sur AppBarLayout:

 Android:fitsSystemWindows="true"

* MISE À JOUR *

J'ai essayé et cela ne suffit pas, car la barre d'outils est toujours défilante. La solution consiste à faire une logique sur ViewPager (et son contenu).

Supprimez du fichier de disposition xml l'attribut scroll_flag de la barre d'outils. Vous devez implémenter du code Java pour vérifier si la hauteur du contenu ViewPager est> puis screenHeight - (barre d'outils + tabBar). Si la valeur est true, définissez par programmation les scroll_flags comme suit:

 LayoutParams params;
 params = // get layout params from your toolbar

 params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);

 // set params
 toolbar.setLayoutParams(params);
0
lubilis

je viens d'avoir le même problème. La solution est très simple, il suffit de régler la hauteur de votre viseur

Android:layout_height="wrap_content"
0
irfan.k

La hauteur ViewPager doit être match_parent et pas wrap_content.

0
marcerv