wake-up-neo.com

Android CoordinatorLayout + AppbarLayout + Viewpager immer scrollen

Ich habe ein klassisches Layout mit einer Symbolleiste oben, einem TabLayout darunter und einem ViewPager, der die Registerkarten im TabLayout wechselt. Wenn der Inhalt im ViewPager gescrollt werden kann, sollte die Symbolleiste nicht sichtbar sein und das TabLayout sollte folgen und haften bleiben, wenn es oben angekommen ist.

All dies ist in meinem aktuellen Code gut, außer dass die Symbolleiste unabhängig von der Größe des ViewPager-Inhalts immer scrollbar ist. Siehe meinen Code unten. Irgendwelche brillanten Ideen, wie man das behebt?

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

BEARBEITEN:

Ich kann sehen, dass die Höhe des viewPagers der Höhe der gesamten Stammansicht entspricht. Dies könnte beabsichtigt sein, da das appbar_scrolling_view_behavior einen oberen und unteren Versatz hinzuzufügen scheint. Es scheint jedoch seltsam, da es dazu führt, dass die Symbolleiste und die Registerkarten immer gescrollt werden.

27
Kenneth

Basierend auf anderen Beispielen, meinem eigenen Code und dem (etwas chaotischen) Quellcode des 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;
    }

Ich lese dies auf eine Art und Weise, die das Problem erklärt, da dieses Verhalten mit diesem Code erwartet wird.

Ich denke, wir müssen unser eigenes Scroll-Verhalten schreiben, speziell für den RecyclerView.

0
Kenneth

Ich habe das Problem behoben, das Beispiel-Google-Template ausprobiert und das herausgefunden

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

die Zeile muss in die XML-Ansichts-Pager-Eigenschaften eingefügt werden. Es hat mein Problem gelöst.

6
Mert

Ich schlug vor, Sie versuchen diese Probe.

dies ist ein Layout wie Ihr Layout im Beispiel.

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

verwenden Sie ListView als Daten für ViewPager? Wenn ja, brauchen Sie listView.setNestedScrollingEnabled(true);

2
a442509097

Versuchen Sie, diese Attribute in TabLayout hinzuzufügen:

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

Und das auf AppBarLayout:

 Android:fitsSystemWindows="true"

* UPDATE *

Ich habe es versucht und das ist nicht genug, da die Symbolleiste noch scrollbar ist. Die Lösung besteht darin, einige logische Überlegungen zu ViewPager (und seinem Inhalt) anzustellen.

Entfernen Sie das Attribut scroll_flag aus der XML-Layoutdatei. Sie müssen einen Java Code implementieren, um zu überprüfen, ob die ViewPager-Inhaltshöhe> und dann screenHeight - (Symbolleiste + TabBar) ist. Wenn true, setzen Sie die scroll_flags programmgesteuert wie folgt:

 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

ich hatte gerade das gleiche Problem. Die Lösung ist sehr einfach, stellen Sie einfach die Höhe Ihres Viewpagers ein

Android:layout_height="wrap_content"
0
irfan.k

Die ViewPager Höhe sollte match_parent Und nicht wrap_content Sein.

0
marcerv