ViewPager в NestedScrollView


112

Мне нужно создать интерфейс, подобный Google Newsstand, который является своего рода ViewPager (горизонтальная прокрутка) над сворачивающимся заголовком (вертикальная прокрутка). Одно из моих требований - использовать новую библиотеку поддержки дизайна, представленную на Google IO 2015. ( http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

Основываясь на образце, созданном Крисом Бэйнсом ( https://github.com/chrisbanes/cheesesquare ), я достиг точки, в которой я могу выполнять сворачивающееся поведение, но с базовым LinearLayout (без горизонтальной прокрутки).

Я попытался заменить LinearLayout ViewPager и получил пустой экран. Я играл с: шириной, весом и всеми видами групп просмотра, но ... все еще пустой экран. Похоже, ViewPager и NestedScrollView не нравятся друг другу.

Я попробовал обходной путь, используя HorizontalScrollView: он работает, но я теряю преимущества функции PagerTitleStrip и фокусировки на одной панели (я могу остановить горизонтальное перемещение между двумя панелями).

Теперь у меня нет больше идей, может ли кто-нибудь подвести меня к решению ...

Спасибо

Вот мой последний файл макета:

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

Вы пробовали завернуть ViewPagerвнутрь LinearLayout? Просто любопытно, ViewPagerправильно ли это отобразит .
CzarMatt 01

Да, я пробовал, но результат тот же. Я провел много тестов со многими компонентами, но ViewPager никогда не отображается в NestedScrollView независимо от иерархии
Kyso84 01

Я только что создал тестовое приложение с ViewPagerвнутренним элементом в NestedScrollViewкачестве единственных макетов - похоже, все работает нормально. Я также смог DrawerLayoutуспешно попасть в . Возможно, есть еще один аспект вашего кода, препятствующий желаемой функциональности. Хотите поделиться своими источниками?
CzarMatt 01

Ух ты, так ты можешь проводить пальцем влево / вправо и вверх / вниз? Я просто использую FragmentPagerAdapter для отображения фрагментов на моем пейджере. Можете ли вы вместо этого поделиться своим примером кода?
Kyso84 01

Я вставил сюда простой пример макета: pastebin.com/jXPw6mtf Edit: вы можете загрузить любой фрагмент, который хотите, в файл ViewPager. Я могу прокручивать просмотры вверх и вниз, а также ViewPagerвлево / вправо.
CzarMatt 01

Ответы:


128

Я встречаюсь с этой проблемой, я решаю ее 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"/>

в действии

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

введите описание изображения здесь


31
Обратите внимание, что это также можно установить в XML, просто добавьте android:fillViewport="true"к NestedScrollViewобъекту. В документации этот атрибут описывается как Defines whether the scrollview should stretch its content to fill the viewport..
Krøllebølle

7
Это не решает проблему прокрутки во фрагментах заполнителя
Atieh

3
Спасибо! Я сел android:fillViewport="true"на NestedScrollViewи внутри fragmentу меня , listViewгде я сидел android:nestedScrollingEnabled="true".. Исправлен скроллинг вопрос
radubogdan

@ Krøllebølle NestedScrollView не имеет этого атрибута, вы должны установить его программно.

Да, это работает для меня. У меня проблема, когда я устанавливаю высоту окна просмотра на match_parent внутри NestedScrollView, он не отображает представления.
Вахид Назир

71

Хорошо, я сделал небольшую демонстрацию с помощью ViewPagerи NestedScrollView. Проблема, с которой я столкнулся, заключалась в высоте ViewPagerи высоте ListView. Поэтому я немного изменил ListViewи ViewPager'sизмерил высоту.

Если кто-то захочет изучить код, вот ссылка: https://github.com/TheLittleNaruto/SupportDesignExample/

Вывод:

введите описание изображения здесь


не работает, если у фрагмента нет списка, даже если список работает, если количество элементов одинаково для всех фрагментов.
Панкадж Арора

3
Возможно, я немного опоздал на вечеринку, но я работал над этим сегодня, и у меня есть (в основном) работа с добавлением app: layout_behavior = "@ string / appbar_scrolling_view_behavior" как в ViewPager, так и в родительском представлении каждый фрагмент.
Грэм

1
Несомненно, это работает, но разве это не усложняет проблему? Я решил эту проблему, избавившись от файла NestedScrollViewи используя LinearLayoutвместо него. Каковы были бы преимущества наличия NestedScrollViewболее, LinearLayoutесли вся цель - прокручивать содержимое в ViewPager? Пожалуйста, поправьте меня, если я ошибаюсь. : x Спасибо
Судороги

1
Спасибо вам большое! Я собирался выдернуть волосы, и ваш WrapContentHeightViewPager работает как шарм. Я твой должник!
Mavamaarten

1
Идеальное решение. Спасибо. У меня сработало .. :)
Мрунал

42

Добавьте android:fillViewport="true"в свой NestedScrollView. период.


3
он решает проблему, но высота окна просмотра будет соответствовать родительскому элементу (занимает всю высоту страницы).
Manukumar

29

Вместо того, чтобы размещать ViewPager внутри NestedScrollView, сделайте это наоборот.

Поместите NestedScrollView в дочерние представления внутри ViewPager, который по сути является макетом фрагмента. Также очень вероятно, что вам даже не понадобится использовать NestedScrollView, если макет списка вашего фрагмента очень простой.

Примеры макетов

Схема деятельности:

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

Если вам не нужен TabLayout, вы можете отказаться от LinearLayout и сделать ViewPager автономным. Но обязательно используйте app:layout_behavior="@string/appbar_scrolling_view_behavior"атрибуты ViewPager.

Макет простого фрагмента:

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

Макет сложного фрагмента:

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

Пример приложения: CollapsingToolbarPoc

введите описание изображения здесь


Это тот, который сделал это за меня. Спасибо!
rjr-apps

Привет, Ино, похоже, это работает, но когда я добавляю еще одно представление поверх TabLayout, он ломается. Не могли бы вы помочь?
hushed_voice

Ты спас мне дни. :)
androidXP

это действительно круто и просто :)
asitis

20

Были те же проблемы.

Если поместить NestedScrollView вокруг ViewPager, это не сработает.

Что DID работает, так это размещение NestedScrollView внутри макета фрагмента, который я загружаю внутри 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>


Работает ли это, если контент был макетом координатора с другим NestedScrollView? И прослушивает ли родительский CoordinatorLayout события прокрутки?
Atieh

Эта работа для меня. Я добавляю NestedScrollView к каждому элементу моего ViewPager вместо ViewPager. Спасибо.
jerogaren

У меня есть swipefreshlayout во фрагменте, в соответствии с решением ur, я помещаю NestedScrollview во фрагмент, выше swipeRefreshLayout .., тогда данные не загружаются. Не сработало.
Палак Дарджи

16

вы можете попробовать вот так, viewpager работает нормально, но высота viewpager фиксирована.

я все еще нахожу лучшее решение ... поэтому, пожалуйста, дайте мне знать, что любой момент может сделать это лучше, спасибо

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

Вы пытались инкапсулировать его в "android.support.design.widget.CoordinatorLayout" и сворачивающуюся панель инструментов?
Kyso84 05

Ваши решения, кажется, доказывают, что проблема в высоте. Нашли какие-нибудь улучшения @Paul?
jasxir

3
Это сработало для меня, но мне также пришлось вызвать setFillViewport (true) во вложенном представлении.
larrytech

12

У меня была такая же проблема, и я исправил ее с некоторыми изменениями. ViewPagerне работает внутри NestedScrollView. Проще говоря, ваше ViewPagerпрямое детище CoordinatorLayout. Затем содержимое каждого фрагмента ViewPager должно быть заключено в NestedScrollView. Вот и все.


даже если контент был макетом координатора с другим NestedScrollView?
Atieh

1
Данные просмотра списка фрагментов не загружаются таким образом!
Палак Дарджи

5

Вам не нужно использовать NestedScrollView, чтобы иметь эффекты параллакса. попробуйте что-то вроде этого:

<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
Это будет работать, пока все ваши ViewPagerфрагменты являются эфирными RecyclerViewили NestedScrollView. Если это не так (например ListView), то обходной путь для Lollipop и выше - позвонитьlistView.setNestedScrollingEnabled(true)
AndyDeveloper

наконец то, что работает без добавления дополнительного контейнера для прокрутки! Кстати, вы можете установить этот setNestedScrollingEnabled (true) и в xml: android: nestedScrollingEnabled = "true"
анализатор,

1
Если я запускаю свое приложение, свертываю панель инструментов, находясь на одной вкладке, переключаю вкладку, а затем опускаю панель инструментов вниз, она пуста. Придется переключать вкладки, пока он не свернут, чтобы вернуть его обратно. Так близко, но так далеко :(
я

4

У меня был макет с панелью инструментов приложения с NestedScrollView под ним, затем внутри вложенной панели инструментов был LinearLayout, под LinearLayout был пейджер представления. Идея заключалась в том, что LinearLayout внутри NestedScrollView был исправлен - вы могли перемещаться влево / вправо между представлениями пейджера представлений, но это содержимое не перемещалось, по крайней мере , по горизонтали . Вы по-прежнему сможете прокручивать все содержимое по вертикали из-за вложенного представления прокрутки. Это была идея. Поэтому я установил высоту вложенного NestedScrollView на match_parent, заполнил область просмотра, а затем для всех дочерних макетов / ViewPager на wrap_content.

В моей голове это было правильно. Но это не сработало - ViewPager позволял мне перемещаться влево / вправо, но без вертикальной прокрутки, независимо от того, помещалось ли содержимое страницы просмотра под нижнюю часть текущего экрана или нет. Оказывается, это было в основном потому, что ViewPager не уважает wrap_content на своих различных страницах.

Я обошел это, создав подкласс ViewPager, чтобы он менял высоту в зависимости от текущего выбранного элемента, заставляя его вести себя как 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);
    }
}

Решение было вдохновлено этим ответом . Сработало у меня!


но прокрутка автоматически прокручивается вверх? как это исправить?
Вивек Кумар

4

просто поместите эту строку в NestedScrollView

android:fillViewport="true"

Тонны благодарности. Что делать, если я хочу прокрутить, непосредственно касаясь CollapsingToolbarLayout?
Pratik Saluja

3

Я удалил NestedScrollView из основного макета и вставил его в качестве родительского элемента во все мои макеты фрагментов , которые должны были загружаться в ViewPager, и эта проблема была решена для меня.


3

Используйте ниже настроенный класс, чтобы решить вашу проблему. Не забудьте вызвать метод onRefresh () на 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

У меня была аналогичная проблема (но без CollapsingToolbarLayoutпростого Toolbar+ TabLayoutвнутри AppBarLayout). Я хотел, чтобы панель инструментов скрывалась из поля зрения при прокрутке содержимого ViewPagerвнутри NestedScrollView.

Мой макет выглядел примерно так:

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

Этот макет работал не так, как задумано, но я решил это, просто избавившись от него NestedScrollViewи LinearLayoutвместо этого используя. У меня это сработало сразу на Android Support Library v23.1.0. Вот как закончился макет:

<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: На самом деле в моем проекте было два файла макета. Я скопировал и вставил их сюда и попытался структурировать их так, как это будет выглядеть в одном файле. Прошу прощения, если я облажался при копировании, но, пожалуйста, дайте мне знать, если это так, чтобы я мог это исправить.


1

Следующее должно обеспечить правильную высоту пейджера просмотра. Фрагмент - это первый фрагмент, предоставленный пейджером просмотра.

<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

У меня такое же желание, вложить ViewPagerвнутрь NestedScrollView. Но и у меня это не работает. В моем случае он ViewPagerнаходится внутри, Fragmentпоэтому я могу переключать контент в зависимости от взаимодействия с ящиком. Конечно, AppBar, сворачивание и т. Д. И все новые функции библиотеки поддержки должны работать.

Если пользователь вертикально прокручивает страницу в пейджере, я хочу, чтобы другие страницы прокручивались так же, чтобы у пользователя было общее впечатление, будто прокручивается сам пейджер.

Что я сделал и что работает, так это то, что я больше не встраиваю ViewPagerвнутри a NestedScrollView, вместо этого я встраиваю содержимое содержащихся фрагментов внутрь NestedScrollView.

Затем, в случае прокрутки в одном фрагменте, я сообщаю контейнеру новую позицию прокрутки, в которой он хранится.

Наконец, свайпом влево или вправо, обнаруженным с пейджера (с использованием addOnPageChangeListenerпоиска состояний перетаскивания), я сообщаю целевому левому или правому фрагменту, где он должен прокручиваться (на основе сведений о контейнере) для выравнивания из фрагмента, из которого я пришел.


По сути, вы написали свою собственную реализацию ViewPager? Не могли бы вы поделиться кодом по этому поводу?
Джозеф

Я сделал что-то подобное (если я правильно понимаю), то есть сделать линейный макет в макете вашего координатора, который содержит tablayout (если необходимо) и viewpager, вместо вложенного scrollview. Сами фрагменты имеют вложенный scrollview в качестве корневого элемента. Это работает для меня, но я бы предпочел иметь только один nestedscrollview вместо того, чтобы повторять его в каждом фрагменте.
Крис

0

Я знаю одно рабочее решение: вы используете Activity с CoordinatorLayout и используете FrameLayout, контейнер. Затем. используйте диспетчер фрагментов, чтобы поместить фрагмент в контейнер. Например, мой код:

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

И фрагмент:

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

Затем используйте FragmentManager

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

Я думаю, что LinearLayoutвнутри макета фрагмента здесь нет необходимости. См. Мой ответ, я использовал LinearLayoutвместо a FrameLayoutв макете моей деятельности, а корнем моего фрагмента является ViewPager (без обертки макета).
Судороги

0

Проведя часы, пробуя все вышеперечисленные предложения, наконец, я заставил их работать. Ключ положить NestedScrollViewвнутрь PageViewer, и установить layout_behaviorв '@string/appbar_scrolling_view_behavior'течение ДВУХ взглядов. Окончательный макет похож на

<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

вы просто удалили NestedScrollView в своем xml и добавили этот код в свой класс

yourGridView.setNestedScrollingEnabled(true);


0

На самом деле NestedScrollView не обязательно должен быть прямым родственником CollapsingToolbarLayout в CoordinatorLayout. Я добился чего-то действительно причудливого. Appbar_scrolling_view_behavior работает в двух вложенных фрагментах.

Схема моей деятельности:

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

В "контейнере" frameLayout я раздул этот фрагмент:

<android.support.constraint.ConstraintLayout>

    ... some content ...

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

    ...

</android.support.constraint.ConstraintLayout>

И фрагменты внутри этого ViewPager выглядят так:

<RelativeLayout>

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

    ....

</RelativeLayout>

Тот факт, что NestedScrollView может быть настолько глубоко в иерархии дочерних элементов CoordinatorLayout, и поведение прокрутки, которое все еще работает, меня удивило.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.