ViewPager in einer NestedScrollView

111

Ich muss eine Oberfläche wie Google Newsstand erstellen, die eine Art ViewPager (horizontaler Bildlauf) über einem reduzierenden Header (vertikaler Bildlauf) ist. Eine meiner Anforderungen ist die Verwendung der neuen Design Support Library, die auf der Google IO 2015 vorgestellt wird. ( Http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

Basierend auf dem von Chris Banes erstellten Beispiel ( https://github.com/chrisbanes/cheesesquare ) habe ich den Punkt erreicht, an dem ich das Reduktionsverhalten ausführen kann, jedoch mit einem einfachen LinearLayout (ohne horizontalen Bildlauf).

Ich habe versucht, das LinearLayout durch einen ViewPager zu ersetzen, und habe einen leeren Bildschirm erhalten. Ich habe gespielt mit: Breite, Gewicht und allen Arten von Ansichtsgruppen, aber ... immer noch ein leerer Bildschirm. Es scheint, dass ViewPager und NestedScrollView sich nicht mögen.

Ich habe versucht, eine Problemumgehung mithilfe eines HorizontalScrollView zu verwenden: Es funktioniert, aber ich verliere den Vorteil der PagerTitleStrip-Funktion und den Fokus auf ein einzelnes Bedienfeld (ich kann das horizontale zwischen zwei Bedienfeldern stoppen).

Jetzt habe ich keine Ideen mehr, ob mich jemand zu einer Lösung führen kann ...

Vielen Dank

Hier ist meine neueste Layoutdatei:

<?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
quelle
Haben Sie versucht, Ihre ViewPagerin ein zu wickeln LinearLayout? Nur neugierig, ob das das ViewPagerrichtig machen würde .
CzarMatt
Ja, ich habe versucht, aber immer noch das gleiche Ergebnis. Ich habe viele Tests mit vielen Komponenten durchgeführt, aber der ViewPager wird unabhängig von der Hierarchie nie in einer NestedScrollView gerendert
Kyso84
Ich habe gerade eine Test-App mit einem ViewPagerInside-A NestedScrollViewals einzigem Layout erstellt - schien gut zu funktionieren. Ich konnte auch DrawerLayouterfolgreich in eine fallen . Vielleicht gibt es einen anderen Aspekt Ihres Codes, der die gewünschte Funktionalität verhindert. Möchten Sie mehr von Ihrer Quelle teilen?
CzarMatt
Wow, also kannst du nach links / rechts und oben / unten wischen? Ich verwende einfach einen FragmentPagerAdapter, um Fragmente in meinem Pager anzuzeigen. Können Sie stattdessen Ihren Beispielcode freigeben?
Kyso84
Ich habe hier ein einfaches Beispiellayout eingefügt: pastebin.com/jXPw6mtf Bearbeiten: Sie können jedes gewünschte Fragment in das laden ViewPager. Ich kann die Ansichten nach oben und unten sowie nach ViewPagerlinks / rechts scrollen .
CzarMatt

Antworten:

128

Ich treffe dieses Problem, ich löse es durch 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"/>

in der Aktivität

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

Geben Sie hier die Bildbeschreibung ein

mio4kon
quelle
31
Beachten Sie, dass dies auch in XML festgelegt werden kann. Fügen Sie es einfach android:fillViewport="true"dem NestedScrollViewObjekt hinzu. In der Dokumentation wird dieses Attribut als beschrieben Defines whether the scrollview should stretch its content to fill the viewport..
Krøllebølle
7
Dies löst nicht das Bildlaufproblem in Platzhalterfragmenten
Atieh
3
Vielen Dank! Ich habe android:fillViewport="true"auf NestedScrollViewund in der fragmentich listViewsaß, wo ich saß android:nestedScrollingEnabled="true". Das Bildlaufproblem wurde
behoben
@ Krøllebølle NestedScrollView hat dieses Attribut nicht, Sie müssen es programmgesteuert festlegen.
Ja das funktioniert bei mir. Ich habe ein Problem, als ich die Höhe des Viewpagers in NestedScrollView auf match_parent gesetzt habe. Die Ansichten wurden nicht angezeigt.
Waheed Nazir
70

Okay, ich habe eine kleine Demo mit dem ViewPagerund gemacht NestedScrollView. Das Problem, mit dem ich konfrontiert war, war die Höhe ViewPagerund die ListView. Also habe ich eine kleine Änderung an ListViewund ViewPager'sHöhenmessung vorgenommen.

Wenn jemand in den Code schauen möchte, ist hier der Link: https://github.com/TheLittleNaruto/SupportDesignExample/

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

TheLittleNaruto
quelle
funktioniert nicht, wenn das Fragment keine Listenansicht hat, auch nicht für die Listenansicht, wenn die Anzahl der Elemente für alle Fragmente gleich ist.
Pankaj Arora
@Dev Das Problem ist die Höhe von View Pager. Unabhängig von der Höhe des ersten Fragments ist die Höhe auch für andere Fragmente gleich. In diesem Fall müssen Sie eine Möglichkeit finden, die Höhe des ViewPager dynamisch festzulegen, indem Sie die Elementmenge für jedes Fragment berücksichtigen.
TheLittleNaruto
3
Ich bin vielleicht etwas spät zur Party, aber ich habe heute daran gearbeitet, und ich habe es (meistens) damit zu tun, App hinzuzufügen: layout_behavior = "@ string / appbar_scrolling_view_behavior" sowohl im ViewPager als auch in der übergeordneten Ansicht von jedes Fragment.
Graeme
1
Kein Zweifel, dass dies funktioniert, aber ist das Problem nicht zu kompliziert? Ich habe das gelöst, indem ich das losgeworden bin NestedScrollViewund stattdessen ein LinearLayoutverwendet habe. Was wären die Vorteile eines NestedScrollViewOver a, LinearLayoutwenn der gesamte Zweck darin besteht, den Inhalt im ViewPager zu scrollen? Bitte korrigieren Sie mich, wenn ich falsch liege. : x Danke
Krämpfe
1
Ich danke dir sehr! Ich war gerade dabei, mir die Haare auszureißen, und Ihr WrapContentHeightViewPager funktioniert wie ein Zauber. Ich schulde dir etwas!
Mavamaarten
42

Fügen Sie android:fillViewport="true"in Ihrem NestedScrollView. Zeitraum.

Sujit Yadav
quelle
2
Es löst das Problem, aber die Viewpager-Höhe ist das übergeordnete Element (es wird die gesamte Seitenhöhe benötigt).
Manukumar
27

Anstatt ViewPager in NestedScrollView zu platzieren, machen Sie es umgekehrt.

Platzieren Sie die NestedScrollView in den untergeordneten Ansichten im ViewPager, der im Wesentlichen das Layout des Fragments darstellt. Es ist auch sehr wahrscheinlich, dass Sie NestedScrollView nicht einmal verwenden müssen, wenn das Listenlayout Ihres Fragments sehr einfach ist.

Beispiellayouts

Layout der Aktivität:

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

Wenn Sie das TabLayout nicht benötigen, können Sie das LinearLayout fallen lassen und ViewPager eigenständig machen. Aber seien Sie sicher, zu verwendenapp:layout_behavior="@string/appbar_scrolling_view_behavior" unbedingt die ViewPager-Attribute.

Layout des einfachen Fragments:

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

Layout des komplexen Fragments:

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

Beispiel-App: CollapsingToolbarPoc

Geben Sie hier die Bildbeschreibung ein

Ino
quelle
Dies ist derjenige, der es für mich getan hat. Vielen Dank!
rjr-apps
Hey Ino, das scheint zu funktionieren, aber wenn ich noch eine Ansicht über dem TabLayout hinzufüge, ist es kaputt. Könnten Sie uns helfen?
hushed_voice
Du hast meine Tage gerettet. :)
androidXP
20

Hatte die gleichen Probleme.

Wenn Sie NestedScrollView um den ViewPager legen, funktioniert dies nicht.

Was jedoch funktioniert hat, ist, die NestedScrollView in das Layout des Fragments einzufügen, das ich in den ViewPager lade.

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

Diese Knochen
quelle
Funktioniert es, wenn der Inhalt ein Koordinatorlayout mit einem anderen NestedScrollView war? Und hört das übergeordnete CoordinatorLayout die Scroll-Ereignisse dort ab?
Atieh
Diese Arbeit für mich. Ich füge die NestedScrollView jedem Element meines ViewPagers anstelle des ViewPagers hinzu. Vielen Dank.
Jerogaren
Ich habe Swipefreshlayout in Fragment, gemäß Ihrer Lösung habe ich NestedScrollview in Fragment über swipeRefreshLayout gesetzt. Dann werden keine Daten geladen. Es hat nicht funktioniert.
Palak Darji
16

Sie können es so versuchen, Viewpager funktioniert einwandfrei, aber die Höhe des Viewpagers ist festgelegt.

Ich finde immer noch die bessere Lösung ..., also lassen Sie mich bitte wissen, dass jeder Punkt es besser machen kann, danke

<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
quelle
Haben Sie versucht, es in ein "android.support.design.widget.CoordinatorLayout" und eine reduzierende Symbolleiste zu kapseln?
Kyso84
Ihre Lösungen scheinen zu beweisen, dass das Problem in der Höhe liegt. Noch Verbesserungen gefunden @Paul?
Jasxir
3
Dieser hat bei mir funktioniert, aber ich musste auch setFillViewport (true) in der verschachtelten Ansicht aufrufen.
Larrytech
12

Ich hatte das gleiche Problem und habe es nur mit einigen Änderungen behoben. ViewPagerfunktioniert nicht innerhalb der NestedScrollView. Setzen Sie einfach ViewPagerals direktes Kind von Ihnen CoordinatorLayout. Dann sollte der Inhalt für jedes ViewPager-Fragment eingeschlossen sein NestedScrollView. Das ist es.

BST Kaal
quelle
selbst wenn der Inhalt ein Koordinatorlayout mit einem anderen NestedScrollView war?
Atieh
1
Fragmentlistenansichtsdaten werden auf diese Weise nicht geladen!
Palak Darji
5

Sie müssen NestedScrollView nicht verwenden, um die Parallaxeeffekte zu erzielen. versuchen Sie so etwas:

<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
quelle
3
Dies wird funktionieren, solange alle Ihre ViewPagerFragmente Äther sind RecyclerView, oder NestedScrollView. Wenn dies nicht der ListViewlistView.setNestedScrollingEnabled(true)
Fall
Endlich etwas, das funktioniert, ohne einen zusätzlichen Scrolling-Container hinzuzufügen! Übrigens können Sie dieses setNestedScrollingEnabled (true) auch in XML setzen: android: nestedScrollingEnabled = "true"
Analizer
1
Wenn ich meine App starte, reduziere ich die Symbolleiste auf einer Registerkarte, wechsle die Registerkarte und ziehe die Symbolleiste wieder nach unten. Sie ist leer. Sie müssen die Tabs wechseln, während sie sich im nicht reduzierten Zustand befinden, um sie wieder zu erhalten. So nah und doch so fern :(
me--
4

Ich hatte ein Layout mit einer App-Symbolleiste mit NestedScrollView darunter, dann befand sich in der verschachtelten Symbolleiste ein LinearLayout, unter dem LinearLayout ein Ansichtspager. Die Idee war, dass das LinearLayout in der NestedScrollView behoben wurde - Sie konnten zwischen den Ansichten des Ansichtspagers nach links / rechts schieben, aber dieser Inhalt bewegte sich zumindest horizontal nicht . Aufgrund der verschachtelten Bildlaufansicht sollten Sie weiterhin in der Lage sein, den gesamten Inhalt vertikal zu scrollen. Das war die Idee. Also habe ich die verschachtelte NestedScrollView-Höhe auf match_parent gesetzt, das Ansichtsfenster gefüllt und dann alle untergeordneten Layouts / ViewPager auf wrap_content gesetzt.

In meinem Kopf war das richtig. Aber es hat nicht funktioniert - ViewPager erlaubte mir, nach links / rechts zu gehen, aber kein vertikales Scrollen, unabhängig davon, ob der Inhalt der Viewpager-Seite unter den unteren Rand des aktuellen Bildschirms verschoben wurde oder nicht. Es stellte sich heraus, dass dies im Grunde darauf zurückzuführen ist, dass der ViewPager wrap_content auf seinen verschiedenen Seiten nicht berücksichtigt.

Ich habe dies umgangen, indem ich den ViewPager in Unterklassen unterteilt habe, damit er die Höhe abhängig vom aktuell ausgewählten Element ändert, und ihn dazu gezwungen hat, sich wie layout_height = "wrap_content" zu verhalten:

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

Die Lösung wurde von dieser Antwort inspiriert . Hat für mich gearbeitet!

Breeno
quelle
aber die Bildlaufansicht scrollt automatisch nach oben? Wie kann man das beheben?
Vivek Kumar
4

Fügen Sie diese Zeile einfach in NestedScrollView ein

android:fillViewport="true"
Gholam
quelle
Tonnenweise Dank. Was tun, wenn ich scrollen möchte, indem ich CollapsingToolbarLayout direkt berühre?
Pratik Saluja
3

Ich entfernte NestedScrollView vom Haupt Layout und als eingefügt Elternteil in all meinem Fragment - Layout , die in zu laden sollten ViewPager für mich , dieses Problem behoben.

Riddhish Ojha
quelle
3

Verwenden Sie die unten angepasste Klasse, um Ihr Problem zu beheben. Vergessen Sie nicht, die onRefresh () -Methode auf pagechangelistener aufzurufen.

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

Ich hatte ein ähnliches Problem (aber ohne CollapsingToolbarLayout, nur ein einfaches Toolbar+ TabLayoutinnerhalb der AppBarLayout). Ich wollte, dass die Symbolleiste außer Sichtweite rollt, wenn der Inhalt von a ViewPagerinnerhalb der NestedScrollView.

Mein Layout sah ungefähr so ​​aus:

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

Dieses Layout funktionierte nicht wie beabsichtigt, aber ich löste es, indem ich es einfach loswurde NestedScrollViewund stattdessen ein LinearLayoutverwendete. Es funktionierte sofort für mich in der Android Support Library v23.1.0. So endete das Layout:

<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: Das waren eigentlich zwei Layoutdateien in meinem Projekt. Ich habe sie hier kopiert und eingefügt und versucht, sie so zu strukturieren, wie es in einer einzelnen Datei aussehen würde. Es tut mir leid, wenn ich beim Einfügen Fehler gemacht habe, aber bitte lassen Sie mich wissen, ob dies der Fall ist, damit ich das Problem beheben kann.

Krämpfe
quelle
1

Das Folgende sollte die richtige Höhe des Ansichtspagers sicherstellen. Das Fragment ist das erste Fragment, das vom Ansichtspager bereitgestellt wird.

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

Ich habe den gleichen Wunsch, ein ViewPagerin a zu nisten NestedScrollView. Aber es funktioniert auch nicht bei mir. In meinem Fall ist das ViewPagerin einemFragment sodass ich den Inhalt abhängig von den Interaktionen mit der Schublade wechseln kann. Natürlich müssen AppBar, Collapse usw. und alle neuen Funktionen der Support-Bibliothek funktionieren.

Wenn ein Benutzer eine Seite im Pager vertikal scrollt, möchte ich, dass andere Seiten gleich gescrollt werden, um dem Benutzer den Gesamteindruck zu vermitteln, dass der Pager selbst gescrollt hat.

Was ich getan habe, was funktioniert, ist, dass ich nicht mehr das ViewPagerInnere a einbette NestedScrollView, sondern den Inhalt der enthaltenen Fragmente in a einbette NestedScrollView.

Im Falle einer Schriftrolle in einem Fragment informiere ich den Container dann über die neue Bildlaufposition, in der sie gespeichert ist.

Schließlich addOnPageChangeListenerinformiere ich das linke oder rechte Zielfragment über einen vom Pager erkannten Wisch nach links oder rechts (unter Verwendung der Suche nach Ziehzuständen), wo es scrollen muss (basierend auf dem Containerwissen darüber), um von dem Fragment ausgerichtet zu werden, von dem ich komme.

François Perret
quelle
Sie haben also im Wesentlichen Ihre eigene ViewPager-Implementierung geschrieben? Könnten Sie Code dazu freigeben?
Joseph
Ich habe etwas Ähnliches gemacht (wenn ich es richtig verstehe), nämlich ein lineares Layout in Ihrem Koordinatorlayout zu erstellen, das das Tablayout (falls erforderlich) und den Viewpager anstelle einer verschachtelten Bildlaufansicht enthält. Die Fragmente selbst haben dann die verschachtelte Bildlaufansicht als Stammelement. Dies funktioniert für mich, aber ich würde es vorziehen, nur eine verschachtelte Bildlaufansicht zu haben, anstatt sie in jedem Fragment zu wiederholen.
Chris
0

Ich kenne eine funktionierende Lösung: Sie verwenden Activity mit CoordinatorLayout und FrameLayout, Container. Dann. Verwenden Sie den Fragment-Manager, um das Fragment in den Container zu legen. Zum Beispiel mein 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>

Und 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" />

Verwenden Sie dann FragmentManager

getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MainFragment())
            .commit();
rz0
quelle
Ich denke, das LinearLayoutLayout innerhalb des Fragments ist hier nicht notwendig. Siehe meine Antwort, ich habe im Layout meiner Aktivität ein LinearLayoutanstelle von a verwendet FrameLayout, und das Stammverzeichnis meines Fragments ist ein ViewPager (kein Wrapping-Layout).
Krämpfe
0

Nachdem ich stundenlang alle oben genannten Vorschläge ausprobiert hatte, ließ ich es endlich funktionieren. Der Schlüssel setzt NestedScrollViewinnen PageViewer, und legen Sie layout_behaviorauf '@string/appbar_scrolling_view_behavior'für BEIDE Ansichten. Das endgültige Layout ist wie

<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>
Beruhigungsmittel
quelle
0

Sie haben gerade die NestedScrollView in Ihrer XML entfernt und diesen Code in Ihre Klasse eingefügt

yourGridView.setNestedScrollingEnabled(true);

Rivaldy Firmansyah
quelle
0

Tatsächlich muss NestedScrollView kein direktes Geschwister von CollapsingToolbarLayout in CoordinatorLayout sein. Ich habe etwas wirklich Bizzares erreicht. Das appbar_scrolling_view_behavior arbeitet in 2 verschachtelten Fragmenten.

Mein Aktivitätslayout:

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

Im "Container" FrameLayout habe ich dieses Fragment aufgeblasen:

<android.support.constraint.ConstraintLayout>

    ... some content ...

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

    ...

</android.support.constraint.ConstraintLayout>

Und Fragmente in diesem ViewPager sehen folgendermaßen aus:

<RelativeLayout>

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

    ....

</RelativeLayout>

Die Tatsache, dass NestedScrollView so tief in der CoordinatorLayout-Kinderhierarchie und im Bildlaufverhalten stecken kann, hat mich überrascht.

Alex Mensak
quelle