NestedScrollView中的ViewPager

Kys*_*o84 102 android android-layout android-viewpager android-support-library

我需要创建一个像Google Newsstand这样的界面,它是一种在折叠标题(垂直滚动)上的ViewPager(水平滚动).我的一个要求是使用Google IO 2015中提供的新设计支持库.(http://android-developers.blogspot.ca/2015/05/android-design-support-library.html)

基于Chris Banes(https://github.com/chrisbanes/cheesesquare)创建的示例,我已经达到了能够执行折叠行为但使用基本LinearLayout(没有水平滚动)的程度.

我试图用ViewPager替换LinearLayout,我得到一个空白屏幕.我玩过:宽度,重量和所有类型的视图组,但....仍然是一个空白的屏幕.似乎ViewPager和NestedScrollView彼此不喜欢.

我通过使用Horizo​​ntalScrollView尝试了一种解决方法:它可以工作,但我放弃了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>
Run Code Online (Sandbox Code Playgroud)

mio*_*kon 120

我遇到了这个问题,我解决了 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"/>
Run Code Online (Sandbox Code Playgroud)

在活动中

  NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nest_scrollview);
    scrollView.setFillViewport (true);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 请注意,这也可以在XML中设置,只需将`android:fillViewport ="true"`添加到`NestedScrollView`对象.[documentation](http://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html)将此属性描述为`定义scrollview是否应拉伸其内容以填充视口. (30认同)
  • 这不能解决占位符片段中的滚动问题 (5认同)
  • 谢谢!我在`NestedScrollView`上坐了`android:fillViewport ="true"`在`fragment`里面我有一个`listView`我坐在那里`android:nestedScrollingEnabled ="true"`..修正了滚动问题 (3认同)

The*_*uto 69

好的,我用ViewPager和做了一个小的演示NestedScrollView.我遇到的问题是高度ViewPager和高度ListView.所以我做了一个小的修改ListViewViewPager's高度测量.

如果有人想查看代码,请点击以下链接:https://github.com/TheLittleNaruto/SupportDesignExample/

输出:

在此输入图像描述

  • 我可能会迟到*但是,我今天正在研究这个问题,而且我(大多数时候)都在使用ViewPager**和*添加app:layout_behavior ="@ string/appbar_scrolling_view_behavior"*在每个片段的父视图上. (3认同)

Suj*_*dav 38

加入 android:fillViewport="true"你的NestedScrollView.期.

  • 它解决了问题,但viewpager高度将是匹配父级(它占整页高度). (2认同)

The*_*nes 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>
Run Code Online (Sandbox Code Playgroud)


小智 19

而不是将ViewPager放在NestedScrollView中,而是以相反的方式进行.

将NestedScrollView放在ViewPager中的子视图中,它实质上是Fragment的布局.如果Fragment的列表布局非常简单,那么你甚至不需要使用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>
Run Code Online (Sandbox Code Playgroud)

如果您不需要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" />
Run Code Online (Sandbox Code Playgroud)

复杂片段的布局:

<?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>
Run Code Online (Sandbox Code Playgroud)

示例应用程序:CollapsingToolbarPoc

在此输入图像描述


小智 15

你可以尝试这样,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>
Run Code Online (Sandbox Code Playgroud)

  • 这个对我有用,但我也必须在nestedview上调用setFillViewport(true). (3认同)

BST*_*aal 10

我有同样的问题,只是修改了一些.ViewPager不起作用NestedScrollView.简单地把你ViewPager作为你的直接孩子CoordinatorLayout.然后应该包含每个ViewPager的片段NestedScrollView内容.而已.


A.H*_*ein 9

只需将此行放在 NestedScrollView 中

android:fillViewport="true"
Run Code Online (Sandbox Code Playgroud)

  • 将“ app:layout_behavior="@string/appbar_scrolling_view_behavior" ”添加到您的 NestedScrollView (2认同)

Bre*_*eno 6

我有一个布局,其中有一个应用程序工具栏,其下方有 NestedScrollView,然后嵌套工具栏内是一个 LinearLayout,在 LinearLayout 下方是一个视图分页器。想法是 NestedScrollView 内的 LinearLayout 是固定的 - 您可以在视图寻呼机的视图之间向左/向右滑动,但此内容不会移动,至少水平移动。由于嵌套滚动视图,您仍然应该能够垂直滚动所有内容。这就是我的想法。所以我将嵌套的NestedScrollView高度设置为match_parent,填充视口,然后将所有子布局/ViewPager设置为wrap_content。

在我看来这是对的。但它不起作用 - ViewPager 允许我向左/向右移动,但不允许垂直滚动,无论 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案受到这个答案的启发。为我工作!


小智 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>
Run Code Online (Sandbox Code Playgroud)

  • 只要所有`ViewPager`片段都是ether`ReclolerView`或`NestedScrollView`,这都可以.如果它们不是(例如`ListView`),那么Lollipop及以上的解决方法是调用`listView.setNestedScrollingEnabled(true)` (3认同)

小智 5

使用以下自定义类来解决您的问题。不要忘记在 pagechangelistener 上调用 onRefresh() 方法。

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)