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

RecyclerView inside a ScrollView/NestedScrollView does not scroll properly

我有一个布局,其中有一个 CardView 和一个 FloatingActionButton 与之关联。 CardView 下方有一个回复列表(这是一个 RecyclerView)。有时 CardViews' 高度大于屏幕,所以我使用 layout_height="wrap_content" 作为 CardView 并将整个 LinearLayout 包裹在 ScrollView.

但是,这会在滚动 RecyclerView 的项目时导致问题(因为它是 ScrollView 中的滚动视图)。正如一些 questions and answers 帖子中所建议的那样,我同时使用了 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>

这是一些图片 -

当您的布局中有多个滚动视图(例如 RecyclerView + ScrollView)并且当您在您的 recyclerView 中滚动时,recyclerView 会与父 Scrollview 一起滚动。这会导致 RecyclerView 出现抖动。您可以通过以下方式避免这种抖动。

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

如果你想在 ScrollView 内部滚动 RecyclerView 并且 ScrollView 阻止滚动 RecyclerView(在 API 16 中发生)你应该使用 android.support.v4.widget.NestedScrollView 而不是 ScrollView 并且您还必须设置 nestedScrollView.setNestedScrollingEnabled(假); 通过这种方式,您可以防止在滚动 RecyclerView 时滚动 nestedScrollView。 希望这对某些人有所帮助

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

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

在你的Activity/Fragment

您必须完成多项任务:

  1. 将你的 recyclerview 放在 android.support.v4.widget.NestedScrollView 而不是正常的 ScrollView
  2. 在布局 XML 文件
  3. 中设置你的 recyclerview android:nestedScrollingEnabled="true"
  4. 要支持早于 API 21 的设备,那么您应该在代码中使用 ViewCompat.setNestedScrollingEnabled(mRecyclerView, false)
  5. 将您的 RecyclerView 高度设置为 android:layout_height="wrap_content"(或宽度,如果它是水平的!)

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

我遇到过 RecyclerView 在标准屏幕上无法正确测量(在大屏幕上)的问题 ScrollView

我有这个问题,解决方法是: 自定义 ScrollView 并将 onInterceptTouchEvent 覆盖为 return false.

希望对某人有所帮助/