ViewPager 内的 ScrollView 不会在 Android 4.x 上滚动

ScrollView inside ViewPager does not scroll on Android 4.x

我有一个问题似乎只影响 Android 4.x 版本,也可能是设备特定的(即它在我的华为 G630@4.3 上不存在,但在三星上存在Ace2@4.4.4)。 我有一个 ScrollView,其中包含一个具有 4 个 CardViewRelativeLayout。现在在某些 4.x 设备上,当我尝试从卡片开始滚动时,滚动事件根本不会发生。如果我触摸卡片之间或 第一张 卡片(而不是任何两张 之间)和设备屏幕之间的小填充,我可以滚动内容。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:app="http://schemas.android.com/tools"
                    xmlns:card_view="http://schemas.android.com/apk/res-auto"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:padding="@dimen/activity_horizontal_margin">

        <android.support.v7.widget.CardView
            android:id="@+id/metricsContainerCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/metrics"/>

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/metrics"
                        android:textSize="20sp"/>
                </LinearLayout>


                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/projectCircleBackgroundShadow"/>

            </LinearLayout>

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

        <android.support.v7.widget.CardView
            android:id="@+id/warningsContainerCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_below="@id/metricsContainerCard"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/bug_color"/>

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/warnings"
                        android:textSize="20sp"/>
                </LinearLayout>


                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/projectCircleBackgroundShadow"/>

            </LinearLayout>
        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:id="@+id/topWarningsContainerCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/warningsContainerCard"
            android:layout_marginTop="10dp"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/top_warnings"/>

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/topWarnings"
                        android:textSize="20sp"/>
                </LinearLayout>


                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/projectCircleBackgroundShadow"/>

            </LinearLayout>
        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:id="@+id/topCriticalItemsContainerCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/topWarningsContainerCard"
            android:layout_marginTop="10dp"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/top_critical_items"/>

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/topCriticalItems"
                        android:textSize="20sp"/>

                </LinearLayout>


                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/projectCircleBackgroundShadow"/>

            </LinearLayout>
        </android.support.v7.widget.CardView>
    </LinearLayout>
</ScrollView>

Android 5.x 和 6.x 没有任何问题。

编辑

看来问题不仅仅与CardView有关,因为我有另一个布局,即使我用自定义视图拖动屏幕也不会滚动:

<ScrollView
    android:id="@+id/scrollView"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".projects.details.ProjectDetailsActivity_">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="vertical"
                  android:padding="@dimen/activity_horizontal_margin">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/projectName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:ellipsize="none"
                android:gravity="center_horizontal"
                android:text="Project name"
                android:textSize="24sp"/>

            <c.f.q.a.projects.details.components.widgets.ProjectDetailWidget
                android:id="@+id/projectDetailWidget"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/timelineWrapperLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.v7.widget.CardView
                android:id="@+id/qualityTimelineCard"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                app:cardElevation="2dp"
                card_view:cardUseCompatPadding="true">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:padding="10dp">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <ImageView
                            android:id="@+id/flipQualityTimelineButton"
                            android:layout_width="30dp"
                            android:layout_height="30dp"
                            android:layout_marginRight="5dp"
                            android:src="@drawable/flip_to_cost"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:ellipsize="end"
                            android:lines="1"
                            android:text="@string/project_timeline_title"
                            android:textSize="16dp"/>
                    </LinearLayout>

                    <ProgressBar
                        android:id="@+id/projectQualityTimelineProgressBar"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        />

                    <com.github.mikephil.charting.charts.LineChart
                        android:id="@+id/projectQualityTimeline"
                        android:layout_width="match_parent"
                        android:layout_height="200dp"
                        android:layout_marginTop="16dp"
                        android:tag="@string/project_chart_tag"
                        android:visibility="gone"/>
                </LinearLayout>
            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                android:id="@+id/costTimelineCard"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:visibility="gone"
                app:cardElevation="2dp"
                card_view:cardUseCompatPadding="true">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:padding="10dp">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <ImageView
                            android:id="@+id/flipCostTimelineButton"
                            android:layout_width="30dp"
                            android:layout_height="30dp"
                            android:layout_marginRight="5dp"
                            android:src="@drawable/flip_to_quality"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:ellipsize="end"
                            android:lines="1"
                            android:text="@string/project_cost_timeline_title"
                            android:textSize="16dp"/>
                    </LinearLayout>


                    <ProgressBar
                        android:id="@+id/projectCostTimelineProgressBar"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        />

                    <com.github.mikephil.charting.charts.LineChart
                        android:id="@+id/projectCostTimeline"
                        android:layout_width="match_parent"
                        android:layout_height="200dp"
                        android:layout_marginTop="16dp"
                        android:tag="@string/project_chart_tag"
                        android:visibility="gone"/>
                </LinearLayout>
            </android.support.v7.widget.CardView>

        </LinearLayout>

        <android.support.v7.widget.CardView
            android:id="@+id/vcsChangeCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_weight="1"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/expandVcsChangeButton"
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/expand_chart"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical"
                        android:ellipsize="end"
                        android:maxLines="2"
                        android:text="@string/project_vcschange_title"
                        android:textSize="16sp"/>
                </LinearLayout>

                <ProgressBar
                    android:id="@+id/vcsChangeProgressBar"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"/>

                <com.github.mikephil.charting.charts.BarChart
                    android:id="@+id/projectVcsChange"
                    android:layout_width="match_parent"
                    android:layout_height="175dp"
                    android:layout_marginTop="16dp"
                    android:tag="@string/project_chart_tag"
                    android:visibility="gone"/>
            </LinearLayout>
        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:id="@+id/dtnosChangeCard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_weight="1"
            app:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:orientation="vertical"
                android:padding="10dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/expandDtnosChangeButton"
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:layout_marginRight="5dp"
                        android:src="@drawable/expand_chart"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical"
                        android:ellipsize="end"
                        android:maxLines="2"
                        android:text="@string/project_systemchange_title"
                        android:textSize="16sp"/>
                </LinearLayout>

                <ProgressBar
                    android:id="@+id/dtnosChangeProgressBar"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"/>

                <com.github.mikephil.charting.charts.BarChart
                    android:id="@+id/projectDtnosChange"
                    android:layout_width="match_parent"
                    android:layout_height="175dp"
                    android:layout_marginTop="16dp"
                    android:tag="@string/project_chart_tag"
                    android:visibility="gone"/>
            </LinearLayout>
        </android.support.v7.widget.CardView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <android.support.v7.widget.CardView
                android:id="@+id/sensorNodeCard"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                app:cardElevation="2dp"
                card_view:cardUseCompatPadding="true">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="left"
                    android:orientation="vertical"
                    android:padding="10dp">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <ImageView
                            android:id="@+id/expandSensornodeButton"
                            android:layout_width="28dp"
                            android:layout_height="28dp"
                            android:layout_marginRight="5dp"
                            android:src="@drawable/expand_chart"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:ellipsize="end"
                            android:maxLines="2"
                            android:text="@string/project_sensornode_title"
                            android:textSize="16sp"/>
                    </LinearLayout>


                    <ProgressBar
                        android:id="@+id/sensorNodeProgressBar"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"/>

                    <com.github.mikephil.charting.charts.RadarChart
                        android:id="@+id/sensorNodeChart"
                        android:layout_width="match_parent"
                        android:layout_height="175dp"
                        android:layout_marginTop="16dp"
                        android:tag="@string/project_chart_tag"
                        android:visibility="gone"/>
                </LinearLayout>
            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                android:id="@+id/aggregateNodeCard"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                app:cardElevation="2dp"
                card_view:cardUseCompatPadding="true">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="right"
                    android:orientation="vertical"
                    android:padding="10dp">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <ImageView
                            android:id="@+id/expandAggregateButton"
                            android:layout_width="28dp"
                            android:layout_height="28dp"
                            android:layout_marginRight="5dp"
                            android:src="@drawable/expand_chart"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:ellipsize="end"
                            android:maxLines="2"
                            android:text="@string/project_aggregatenode_title"
                            android:textSize="16sp"/>

                    </LinearLayout>

                    <ProgressBar
                        android:id="@+id/aggregateNodeProgressBar"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"/>

                    <com.github.mikephil.charting.charts.RadarChart
                        android:id="@+id/aggregateNodeChart"
                        android:layout_width="match_parent"
                        android:layout_height="175dp"
                        android:layout_marginTop="16dp"
                        android:tag="@string/project_chart_tag"
                        android:visibility="gone"/>
                </LinearLayout>
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </LinearLayout>
</ScrollView>

我添加了完整的布局,这里还有一张图片用于说明(我标记了可以拖动的可滚动区域):

EDIT2

也许这些布局是 ViewPager 中的片段也很重要。 ViewPager 是否有可能阻止 ScrollView (以及其中的任何其他视图)获得焦点/处理触摸事件?我的 ViewPager 的代码是这样的:

<android.support.v4.view.ViewPager
    android:id="@+id/projectPager"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

EDIT3

看来问题一定出在 ViewPager + (Nested)ScrollView 上(我试图用它交换普通的 ScrollView,但没有成功)。我为我的片段创建了一个虚拟布局,它只包含一个父 NestedScrollView、一个 LinearLayout 和许多像这样的大 TextView

<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".projects.details.ProjectDetailsActivity_">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical"
              android:padding="@dimen/activity_horizontal_margin">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:ellipsize="none"
        android:gravity="center_horizontal"
        android:text="Project name"
        android:textSize="80sp"/>

... <!-- more TextViews come here -->

...滚动也不起作用!和以前一样,只在屏幕的边缘。我不知道怎么会这样...

您的 ScrollView 必须具有 match_parent height 并且 scrollview ( LinearLayout ) 的第一个子项必须具有 wrap_content 高度

你说得对,2 个可滚动控件相互竞争。

改用支持库中的 NestedScrollView。它旨在解决此类问题。

它有许多增强功能,可以与其他可滚动控件一起使用,包括 ViewPagerRecyclerView(只要您调用 .setNestedScrolling(true))和 CoordinatorLayout

基于以上所述,我一直在使用这个新的 class 在所有情况下,滚动中的滚动一直完美运行。我们的产品在 ViewPager 中有完美工作的 NestedScrollView 控件,有些还嵌入了 RecyclerView 列表。

已解决!我有完全相同的问题。您可能正在使用 PageTransformer ViewPager 动画。

为 < Android 4.1 禁用自定义页面转换器解决了这个问题:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        // there are problems with this on 4.0.3, probably also on 4.1
        viewPager.setPageTransformer(true, new DepthPageTransformer());
    }

您的 post 和研究为我节省了很多时间,谢谢。

其他解决方案:

如果您喜欢您的动画,您也可以尝试将您的 DepthPageTransformer 更改为:

对我而言,此设置有效:我有一个 Coordinator 布局,它具有以下嵌套滚动视图

 <android.support.v4.widget.NestedScrollView
    android:layout_marginTop="8dp"
    android:fillViewport = "true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <include layout="@layout/content_app_bar_search_patient_module"/>

</android.support.v4.widget.NestedScrollView>

<include layout="@layout/content_app_bar_search_patient_module"/> 有一个 viewpager,它的片段又包含一个嵌套的 scrollview

<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="match_parent"
    android:layout_height="match_parent">
.
.
.
    </android.support.v4.widget.NestedScrollView>