ViewPager w NestedScrollView


111

Muszę stworzyć interfejs taki jak Google Newsstand, który jest rodzajem ViewPagera (przewijanie w poziomie) nad zwijanym nagłówkiem (przewijanie w pionie). Jednym z moich wymagań jest korzystanie z nowej biblioteki Design Support Library przedstawionej na Google IO 2015. ( http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

Na podstawie próbki stworzonej przez Chrisa Banesa ( https://github.com/chrisbanes/cheesesquare ) doszedłem do punktu, w którym jestem w stanie wykonać zachowanie zwijania, ale z podstawowym LinearLayout (bez przewijania poziomego).

Próbowałem zamienić LinearLayout na ViewPager i otrzymałem pusty ekran. Bawiłem się: szerokością, wagą i wszelkiego rodzaju grupami widoków, ale ... nadal był pusty ekran. Wygląda na to, że ViewPager i NestedScrollView się nie lubią.

Próbowałem obejścia tego problemu za pomocą HorizontalScrollView: działa, ale tracę zalety funkcji PagerTitleStrip i skupienie się na jednym panelu (mogę zatrzymać poziomo między 2 panelami).

Teraz nie mam już pomysłów, jeśli ktoś może mnie doprowadzić do rozwiązania ...

Dzięki

Oto mój najnowszy plik układu:

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

Czy próbowałeś zawinąć swoje ViewPagerwnętrze LinearLayout? Ciekawe, czy to renderuje ViewPagerpoprawnie.
CzarMatt

Tak, próbowałem, ale wciąż ten sam wynik. Wykonałem wiele testów z wieloma komponentami, ale ViewPager nigdy nie jest renderowany w NestedScrollView bez względu na hierarchię
Kyso84

Właśnie stworzyłem aplikację testową z ViewPagerwewnętrznym a NestedScrollViewjako jedynymi układami - wydawało się, że działa dobrze. Udało mi się też z DrawerLayoutpowodzeniem wpaść do . Być może jest inny aspekt twojego kodu uniemożliwiający pożądaną funkcjonalność. Chcesz udostępnić więcej swojego źródła?
CzarMatt

Wow, więc możesz przesuwać palcem w lewo / w prawo i w górę / w dół? Po prostu używam FragmentPagerAdapter do wyświetlania fragmentów na moim pagerze. Czy możesz zamiast tego udostępnić swój przykładowy kod?
Kyso84

Wkleiłem tutaj prosty przykładowy układ: pastebin.com/jXPw6mtf Edycja: Możesz załadować dowolny fragment do pliku ViewPager. Jestem w stanie przewijać widoki w górę iw dół, a także przewijać w ViewPagerlewo / w prawo.
CzarMatt

Odpowiedzi:


128

Spotykam się z tym problemem, rozwiązuję go przez 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"/>

w działalności

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

wprowadź opis obrazu tutaj


31
Zauważ, że można to również ustawić w XML, po prostu dodaj android:fillViewport="true"do NestedScrollViewobiektu. Dokumentacja opisuje to jako atrybut Defines whether the scrollview should stretch its content to fill the viewport..
Krøllebølle

7
To nie rozwiązuje problemu przewijania we fragmentach zastępczych
Atieh

3
Dzięki! Ja siedziałem android:fillViewport="true"na NestedScrollViewi wewnątrz fragmentmam listViewgdzie ja siedziałem android:nestedScrollingEnabled="true".. Naprawiono problem przewijania
radubogdan

@ Krøllebølle NestedScrollView nie ma tego atrybutu, musisz ustawić go programowo.

Tak, to działa dla mnie. Mam problem, kiedy ustawiłem wysokość viewpagera na match_parent w NestedScrollView, nie wyświetlał on widoków.
Waheed Nazir

71

OK, stworzyłem małe demo z ViewPageri NestedScrollView. Problem, z jakim miałem do czynienia, dotyczył wysokości ViewPageri ListView. Zrobiłem więc małą modyfikację ListViewi ViewPager'spomiar wysokości.

Jeśli ktoś chciałby zajrzeć do kodu, oto link: https://github.com/TheLittleNaruto/SupportDesignExample/

Wynik:

wprowadź opis obrazu tutaj


nie działa, jeśli fragment nie ma listview, nawet dla listview działa, jeśli liczba elementów jest taka sama dla wszystkich fragmentów.
Pankaj Arora

3
Być może trochę się spóźniłem na imprezę, ale pracowałem nad tym dzisiaj i udało mi się to (głównie) podczas dodawania app: layout_behavior = "@ string / appbar_scrolling_view_behavior" zarówno na ViewPager, jak i na widoku nadrzędnym każdy fragment.
Graeme

1
Bez wątpienia to działa, ale czy nie komplikuje to zbytnio problemu? Rozwiązałem to, pozbywając się NestedScrollViewi używając LinearLayoutzamiast tego. Jakie byłyby korzyści z posiadania NestedScrollViewponad a, LinearLayoutgdyby celem było przewijanie zawartości w ViewPager? Proszę popraw mnie jeżeli się mylę. : x Thanks
Cramps

1
Dziękuję bardzo! Byłem w momencie wyrywania włosów, a Twój WrapContentHeightViewPager działa jak urok. Jestem ci winny przysluge!
Mavamaarten

1
Idealne rozwiązanie. Dzięki. U mnie zadziałało .. :)
Mrunal

42

Dodaj android:fillViewport="true"swoje NestedScrollView. Kropka.


3
rozwiązuje problem, ale wysokość strony podglądu będzie pasującym rodzicem (zajmie całą wysokość strony).
Manukumar

27

Zamiast umieszczać ViewPager wewnątrz NestedScrollView, zrób to na odwrót.

Umieść NestedScrollView w widokach podrzędnych wewnątrz ViewPager, który w istocie jest układem fragmentu. Jest również bardzo prawdopodobne, że nie będziesz nawet musiał używać NestedScrollView, jeśli układ listy Twojego fragmentu jest bardzo prosty.

Przykładowe układy

Układ działania:

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

Jeśli nie potrzebujesz TabLayout, możesz porzucić LinearLayout i uczynić ViewPager samodzielnym. Ale pamiętaj, aby użyćapp:layout_behavior="@string/appbar_scrolling_view_behavior" atrybutów ViewPager.

Układ prostego fragmentu:

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

Układ złożonego fragmentu:

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

Przykładowa aplikacja: CollapsingToolbarPoc

wprowadź opis obrazu tutaj


To jest ten, który zrobił to dla mnie. Dzięki!
rjr-apps

Hej, Ino, wygląda na to, że działa, ale kiedy dodam jeszcze jeden widok na górze TabLayout, zepsuje się. Czy mógłbyś udzielić pomocy?
hushed_voice

Uratowałeś moje dni. :)
androidXP

20

Miał te same problemy.

Podczas umieszczania NestedScrollView wokół ViewPager nie zadziała.

To, co DID działało, to umieszczenie NestedScrollView w układzie fragmentu, który ładuję, wewnątrz 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>


Czy to działa, jeśli zawartość była układem koordynatora z innym NestedScrollView? I czy nadrzędny CoordinatorLayout nasłuchuje tam zdarzeń przewijania?
Atieh

Ta praca dla mnie. Dodaję NestedScrollView do każdego elementu mojego ViewPager zamiast ViewPager. Dzięki.
jerogaren

Mam swipefreshlayout we fragmencie, zgodnie z rozwiązaniem ur, umieściłem NestedScrollview we fragmencie, powyżej swipeRefreshLayout .. wtedy dane nie są ładowane. To nie zadziałało.
Palak Darji

16

możesz spróbować w ten sposób, przeglądarka działa dobrze, ale wysokość podglądu jest stała.

wciąż znajduję lepsze rozwiązanie ... więc proszę, daj mi znać, że w każdej chwili mogę to zrobić lepiej, dzięki

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

Czy próbowałeś zamknąć go w „android.support.design.widget.CoordinatorLayout” i zwijającym się pasku narzędzi?
Kyso84

Twoje rozwiązania wydają się dowodzić, że problem tkwi na wysokości. Znalazłeś jeszcze jakieś ulepszenia @Paul?
jasxir

3
Ten działał dla mnie, ale musiałem również wywołać setFillViewport (true) w widoku zagnieżdżonym.
larrytech

12

Miałem ten sam problem i po prostu naprawiłem go z pewnymi zmianami. ViewPagernie działa w ramach NestedScrollView. Po prostu umieść swoje ViewPagerjako bezpośrednie dziecko CoordinatorLayout. Następnie zawartość każdego fragmentu ViewPagera powinna być ujęta w NestedScrollView. Otóż ​​to.


nawet jeśli zawartość była układem koordynatora z innym NestedScrollView?
Atieh

1
Fragmentowe dane widoku listy nie są ładowane w ten sposób!
Palak Darji

5

Nie musisz używać NestedScrollView, aby uzyskać efekty paralaksy. spróbuj czegoś takiego:

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

3
To zadziała, o ile wszystkie twoje ViewPagerfragmenty będą eterem RecyclerViewlub NestedScrollView. Jeśli tak nie jest (np. ListView), Obejściem dla Lollipopa i nowszych jest zadzwońlistView.setNestedScrollingEnabled(true)
AndyDeveloper

wreszcie coś, co działa bez dodawania dodatkowego kontenera przewijanego! Przy okazji możesz ustawić ten setNestedScrollingEnabled (true) również w xml: android: nestedScrollingEnabled = "true"
Analizer

1
Jeśli uruchomię moją aplikację, zwijam pasek narzędzi na jednej karcie, przełączam kartę, a następnie pociągam pasek narzędzi z powrotem w dół, jest pusty. Muszę przełączać karty, gdy jest w stanie niezwiniętym, aby je odzyskać. Tak blisko, ale tak daleko :(
ja

4

Miałem układ z paskiem narzędzi aplikacji z NestedScrollView pod nim, następnie wewnątrz zagnieżdżonego paska narzędzi był LinearLayout, poniżej LinearLayout był pager widoku. Pomysł polegał na tym, że LinearLayout wewnątrz NestedScrollView został naprawiony - można było przesuwać w lewo / w prawo między widokami pagera widoku, ale ta zawartość nie poruszała się w poziomie przynajmniej w . Nadal powinno być możliwe przewijanie całej zawartości w pionie ze względu na zagnieżdżony widok przewijania. To był pomysł. Więc ustawiłem zagnieżdżoną wysokość NestedScrollView na match_parent, wypełnij rzutnię, a następnie wszystkie układy potomne / ViewPager na wrap_content.

W mojej głowie to było słuszne. Ale to nie zadziałało - ViewPager pozwolił mi przejść w lewo / w prawo, ale bez przewijania w pionie, niezależnie od tego, czy zawartość strony przeglądarki została przesunięta poniżej dolnej części bieżącego ekranu, czy nie. Okazuje się, że było tak, ponieważ ViewPager nie respektuje zawartości wrap_content na swoich różnych stronach.

Obejrzałem to, podklasując ViewPager, aby zmieniał wysokość w zależności od aktualnie wybranego elementu, w pewnym sensie zmuszając go do zachowania się jak 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);
    }
}

Rozwiązanie zostało zainspirowane tą odpowiedzią . Pracował dla mnie!


ale widok przewijania automatycznie przewija się do góry? jak to naprawić?
Vivek Kumar

4

po prostu umieść tę linię w NestedScrollView

android:fillViewport="true"

Mnóstwo podziękowań. Co zrobić, jeśli chcę przewijać, dotykając bezpośrednio CollapsingToolbarLayout?
Pratik Saluja

3

Usunąłem NestedScrollView z głównego układu i wstawiony jako dominującej we wszystkich moich Fragment układów, które miały obciążenia w ViewPager stałe ten problem dla mnie.


3

Użyj poniższej klasy niestandardowej, aby rozwiązać problem. Nie zapomnij wywołać metody onRefresh () na 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();
        }
    }
}

2

Miałem podobny problem (ale bez CollapsingToolbarLayoutprostego Toolbar+ TabLayoutwewnątrz AppBarLayout). Chciałem, aby pasek narzędzi przewijał się poza zasięgiem wzroku podczas przewijania zawartości pliku ViewPagerwewnątrz NestedScrollView.

Mój układ wyglądał mniej więcej tak:

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

Ten układ nie działał zgodnie z przeznaczeniem, ale rozwiązałem go, po prostu pozbywając się NestedScrollViewi używając LinearLayoutzamiast tego. U mnie zadziałało od razu na Android Support Library w wersji 23.1.0. Oto, jak skończył się układ:

<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: To były właściwie dwa pliki układu w moim projekcie. Skopiowałem i wkleiłem je tutaj i próbowałem uporządkować je tak, jak wyglądałyby w jednym pliku. Przepraszam, jeśli schrzaniłem podczas kopiowania i wklejania, ale daj mi znać, jeśli tak jest, żebym mógł to naprawić.


1

Poniższe czynności powinny zapewnić odpowiednią wysokość pagera widoku. Fragment jest pierwszym fragmentem udostępnionym przez pager widoku.

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

1

Mam to samo życzenie, zagnieździć ViewPagerwewnątrz a NestedScrollView. Ale na mnie też nie działa. W moim przypadku ViewPagerznajduje się wewnątrz a, Fragmentwięc mogę przełączać zawartość w zależności od interakcji z szufladą. Oczywiście AppBar, zwijanie itp. Oraz wszystkie nowe funkcje biblioteki wsparcia muszą działać.

Jeśli użytkownik przewija stronę w pagerze w pionie, chcę, aby inne strony przewijały się tak samo, aby użytkownik miał ogólne wrażenie, że przewijał się sam pager.

To, co zrobiłem, co działa, polega na tym, że nie osadzam już ViewPagerwewnątrz a NestedScrollView, zamiast tego osadzam zawartość zawartych fragmentów w NestedScrollView.

Następnie w przypadku przewijania w jednym fragmencie informuję kontener o nowej pozycji przewijania, która go przechowuje.

Na koniec, po przesunięciu palcem w lewo lub w prawo wykrytym na pagerze (przy użyciu addOnPageChangeListenerwyszukiwania stanów przeciągania) informuję docelowy fragment w lewo lub w prawo, gdzie musi przewinąć (na podstawie wiedzy o kontenerze), aby wyrównać z fragmentu, z którego pochodzę.


Więc zasadniczo napisałeś własną implementację ViewPagera? Czy byłbyś w stanie udostępnić kod na ten temat?
joseph

Zrobiłem coś podobnego do tego (jeśli dobrze to rozumiem), czyli zrobić układ liniowy w układzie koordynatora, który zawiera układ tabeli (w razie potrzeby) i przeglądarkę zamiast zagnieżdżonego widoku przewijania. Same fragmenty mają wtedy zagnieżdżony widok przewijania jako element główny. To działa dla mnie, ale wolałbym mieć po prostu jeden zagnieżdżony widok przewijania zamiast powtarzać go w każdym fragmencie.
Chris,

0

Znam jedno działające rozwiązanie: używasz Activity, z CoordinatorLayout i używasz FrameLayout, kontenera. Następnie. użyj menedżera fragmentów, aby umieścić fragment w kontenerze. Na przykład mój kod:

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

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

Następnie użyj FragmentManager

getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MainFragment())
            .commit();

Myślę, że układ LinearLayoutwewnątrz Fragmentu jest tutaj niepotrzebny. Zobacz moją odpowiedź, użyłem a LinearLayoutzamiast a FrameLayoutw układzie mojego działania, a katalogiem głównym mojego fragmentu jest ViewPager (bez układu zawijania).
Skurcze

0

Po spędzeniu wielu godzin wypróbowałem wszystkie powyższe sugestie, w końcu udało mi się. Kluczem jest umieszczenie NestedScrollViewwewnątrz PageVieweri ustaw layout_behavioraby '@string/appbar_scrolling_view_behavior'dla OBU widokami. Ostateczny układ jest podobny

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

0

właśnie usunąłeś NestedScrollView w swoim XML i dodałeś ten kod do swojej klasy

yourGridView.setNestedScrollingEnabled(true);


0

W rzeczywistości NestedScrollView nie musi być bezpośrednim elementem równorzędnym CollapsingToolbarLayout w CoordinatorLayout. Osiągnąłem coś naprawdę dziwnego. Appbar_scrolling_view_behavior działa w 2 zagnieżdżonych fragmentach.

Układ mojej aktywności:

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

W frameLayout "kontenera" napompowałem ten fragment:

<android.support.constraint.ConstraintLayout>

    ... some content ...

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

    ...

</android.support.constraint.ConstraintLayout>

A fragmenty wewnątrz tego ViewPagera wyglądają następująco:

<RelativeLayout>

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

    ....

</RelativeLayout>

Fakt, że NestedScrollView może być tak głęboko w hierarchii elementów podrzędnych CoordinatorLayout i zachowaniach przewijania, które nadal działa, był dla mnie zaskoczeniem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.