【问题标题】:RecyclerView inside a ScrollView/NestedScrollView does not scroll properlyScrollView/NestedScrollView 内的 RecyclerView 无法正确滚动
【发布时间】:2016-10-20 22:18:19
【问题描述】:

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

但是,在滚动RecyclerView 的项目时,这会导致问题(因为它是ScrollView 内的滚动视图)。正如一些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>

这里有一些图片 -

【问题讨论】:

    标签: android android-recyclerview scrollview


    【解决方案1】:

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

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

    【讨论】:

    • 您能解释一下为什么会这样吗?另外,我必须支持 API v21 之前的设备。
    • 您的布局中有多个滚动视图,因此当您在触摸 recyclerView 的同时滚动时,recyclerView 会随着父 Scrollview 滚动。这会导致 RecyclerView 抖动,因此使用 nestedScrollingEnabled="false" 您有点停止 recyclerView 的滚动,并且触发的唯一滚动来自父 ScrollView。我也使用 .setNestScrollingEnabled() 以编程方式执行此操作,并且在 API v21 之前的设备上工作正常。
    • 我已经接受了答案,但你能用你在评论中提到的东西更新它吗?
    • 因为在上面一行我的最后一张卡片视图被切断了
    • 请注意,如果您想支持比 v21 更早的设备,您必须使用 ViewCompat.setNestedScrollingEnabled(mRecyclerView, false); @yadav_vi
    【解决方案2】:

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

    ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

    在您的活动/片段中

    【讨论】:

    • 你能解释一下为什么我的答案是错误的,我被否决了吗?我想知道我是否弄错了,因为我在我的代码中使用了上面的 sn-p 并且它工作得很好。谢谢
    【解决方案3】:

    你必须完成多项任务:

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

    【讨论】:

      【解决方案4】:

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

      当 RecyclerView 在标准 ScrollView 中时,我遇到了无法正确测量的问题(在大屏幕上)

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          我有这个问题,解决它: 自定义 ScrollView 并覆盖 onInterceptTouchEvent 以返回 false。

          希望对某人有所帮助/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-01
            • 2021-12-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-23
            相关资源
            最近更新 更多