ScrollView / NestedScrollView中的RecyclerView无法正确滚动

时间:2016-06-19 16:19:33

标签: android android-recyclerview scrollview

我的布局中包含CardViewFloatingActionButtonCardView下面有一个回复列表(RecyclerView)。有时CardViews'高度大于屏幕,因此我使用了layout_height="wrap_content" CardView并将整个LinearLayout包裹在ScrollView内。

但是,这会导致问题(因为它是ScrollView内的滚动视图),同时滚动RecyclerView的项目。根据发布的questionsanswers部分建议,我使用了NestedScrollViewandroid:nestedScrollingEnabled="true"标记,但RecyclerView中的滚动仍然不好

这是我的Layout文件 -

<?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"
    tools:context="com.example.forum.reply.ReplyActivity">

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/reply_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:titleTextColor="@android:color/white"/>

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:nestedScrollingEnabled="true"
            android:fillViewport="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="8dp"
                android:orientation="vertical">

                <android.support.v7.widget.CardView
                    android:id="@+id/topic_card"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingBottom="@dimen/card_margin"
                    android:paddingLeft="@dimen/card_margin"
                    android:paddingRight="@dimen/card_margin"
                    android:paddingTop="@dimen/card_margin">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:paddingEnd="@dimen/card_margin"
                        android:paddingStart="@dimen/card_margin">

                        <android.support.v7.widget.AppCompatTextView
                            android:id="@+id/topic_title"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="8dp"
                            android:layout_marginTop="8dp"
                            android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

                        <android.support.v7.widget.AppCompatTextView
                            android:id="@+id/topic_content"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
                    </LinearLayout>
                </android.support.v7.widget.CardView>

                <ProgressBar
                    android:id="@+id/reply_progressbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:indeterminate="true"
                    android:visibility="visible"/>

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/list_of_replies"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="invisible"/>
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/reply_to_topic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:clickable="true"
        android:src="@drawable/ic_reply_white_24dp"
        app:layout_anchor="@id/topic_card"
        app:layout_anchorGravity="bottom|right|end"/>

</android.support.design.widget.CoordinatorLayout>

以下是一些图片 -

CardView with FloatingActionButton visible

Scrolling from the CardView to RecyclerView is smooth

Scrolling down isn't smooth

Scrolling up also isn't smooth

6 个答案:

答案 0 :(得分:12)

如果布局中有多个滚动视图(例如RecyclerView + ScrollView),并且在recyclelerView中滚动时,recyclelerView将使用父Scrollview滚动。这会导致RecyclerView中的抖动。您可以通过以下方式避免此抖动。

您可以在 XML 中将RecycledView的android:nestedScrollingEnabled="false" 添加到您的RecyclerView,或者在 Java 中将您的RecyclerView添加到recyclerView.setNestedScrollingEnabled(false);

答案 1 :(得分:5)

如果您想支持早于api 21的设备,那么您应该使用

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

您的活动/片段中的

答案 2 :(得分:1)

如果你想在ScrollView中滚动RecyclerView并且ScrollView阻止滚动RecyclerView(在API 16中发生这种情况)你应该使用android.support.v4.widget.NestedScrollView 而不是ScrollView,你也必须设置        nestedScrollView.setNestedScrollingEnabled(假); 通过这种方式,您可以在滚动RecyclerView时阻止滚动嵌套的Srollroll。 希望这能有所帮助

答案 3 :(得分:1)

您必须执行多项任务:

  1. 将您的回收站视图放入android.support.v4.widget.NestedScrollView而不是普通的ScrollView
  2. 在布局XML文件中设置您的回收站视图android:nestedScrollingEnabled="true"
  3. 要支持早于API 21的设备,则应在代码中使用ViewCompat.setNestedScrollingEnabled(mRecyclerView, false)
  4. 将RecyclerView的高度设置为android:layout_height="wrap_content"(如果水平,则为宽度!)

答案 4 :(得分:1)

除了设置android:nestedScrollingEnabled="false"外,您还需要确保RecyclerView的父级是android.support.v4.widget.NestedScrollView

我感到麻烦的是,RecyclerView在标准ScrollView中时无法正常测量(在大屏幕上)

答案 5 :(得分:0)

我遇到了这个问题,可以通过以下方法解决: 自定义ScrollView并重写onInterceptTouchEvent以返回false。

希望它能帮助某人/