ScrollView中的Recyclerview无法平滑滚动


179

对于我的应用我使用的是RecyclerView内部的ScrollView,其中RecyclerView有基于使用其内容的高度这个库。滚动正常,但在上滚动时效果不佳RecyclerView。当我滚动ScrollView自身时,它会平滑滚动。

我用来定义的代码RecyclerView

LinearLayoutManager friendsLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), android.support.v7.widget.LinearLayoutManager.VERTICAL, false);
mFriendsListView.setLayoutManager(friendsLayoutManager);
mFriendsListView.addItemDecoration(new DividerItemDecoration(getActivity().getApplicationContext(), null));

RecyclerViewScrollView

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

此解决方案为我工作:stackoverflow.com/a/32390370/7308789谢谢
Houssin Boulla

1
@tahaDev在您的情况下究竟不起作用,请对此进行详细说明。另外,似乎没有提供的解决方案适用于您的情况,是吗?
Pravin Divraniya '19

androidx.constraintlayout.widget.ConstraintLayout无需任何复杂实现即可使用的解决方案
-Saswata

Answers:


379

尝试做:

RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);

或者,您可以使用支持设计库来修改布局。我猜你当前的布局是这样的:

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with custom layoutmanager -->

   </LinearLayout >
</ScrollView >

您可以将其修改为:

<CoordinatorLayout >

    <AppBarLayout >
        <CollapsingToolbarLayout >
             <!-- with your content, and layout_scrollFlags="scroll" -->
        </CollapsingToolbarLayout >
    </AppBarLayout >

    <RecyclerView > <!-- with standard layoutManager -->

</CoordinatorLayout >

但是,这是一条漫长的路,如果您对自定义线性布局管理器感到满意,那么只需在“回收者”视图上禁用嵌套滚动即可。

编辑(4/3/2016)

v 23.2现在,支持库的发行版在所有default中都包含工厂“包装内容”功能LayoutManager。我没有对其进行测试,但是您可能应该比您正在使用的库更喜欢它。

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with wrap_content -->

   </LinearLayout >
</ScrollView >

16
要添加到此答案:setNestedScrollingEnabled(false)仅当我将ScrollViewa NestedScrollView换掉时才有效。
理查德·勒·梅苏里尔

11
对我来说,setNestedScrollingEnabled(false)给我回弹时可以让我RecyclerView在其中滚动ScrollView-谢谢!但我仍然不明白为什么行得通...?将嵌套滚动设置为false到底意味着什么?
Micro

33
请注意,android:nestedScrollingEnabled="false"仅适用于API 21+,而v.setNestedScrollingEnabled(false)对于<21则可以。
Eric B.

3
对于未来的参考,如果有人遇到RecyclerViewWRAP_CONTENT问题里面ScrollView发生在棉花糖/牛轧糖(API 23,24)的设备,检查我的解决方法在stackoverflow.com/a/38995399/132121
侯赛因·汗

2
我现在遇到的该解决方案的缺点是RecyclerView不会在其onScrollListener中接收事件。之所以需要它,是因为当回收站中只有一定数量的物品时,我想获取更多数据
Daniel W.


26

您可以使用以下方式之一:

将此行添加到您的recyclerView xml文件中:

android:nestedScrollingEnabled="false"

或在Java代码中:

RecyclerView.setNestedScrollingEnabled(false);

希望这对您有所帮助。


10
需要Api 21+
穆罕默德·里亚兹

11

您可以尝试使用XML和编程两种方式。但是您可能会遇到的问题是(使用API​​ 21以下)通过XML进行处理将无法正常工作。因此,最好以编程方式在“活动/片段”中进行设置。

XML代码:

<android.support.v7.widget.RecyclerView
      android:id="@+id/recycleView"
      android:layout_width="match_parent"
      android:visibility="gone"
      android:nestedScrollingEnabled="false"
      android:layout_height="wrap_content"
      android:layout_below="@+id/linearLayoutBottomText" /> 

以编程方式:

 recycleView = (RecyclerView) findViewById(R.id.recycleView);
 recycleView.setNestedScrollingEnabled(false);

6

使用嵌套滚动视图而不是滚动视图解决了我的问题

<LinearLayout> <!--Main Layout -->
   <android.support.v4.widget.NestedScrollView>
     <LinearLayout > <!--Nested Scoll View enclosing Layout -->`

       <View > <!-- upper content --> 
       <RecyclerView >


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

5

我遇到了类似的问题(我试图创建一个嵌套的RecyclerViews之类的东西,例如Google PlayStore设计)。解决此问题的最佳方法是将子类RecyclerViews子类化,并覆盖“ onInterceptTouchEvent”和“ onTouchEvent”方法。这样,您可以完全控制这些事件的行为方式以及最终滚动的方式。


3

用NestedScrollView替换ScrollView可以平滑滚动到底部。


1

如果您在子视图中使用VideoView或重量级小部件,则将带有高度的RecyclerView保留在具有高度wrap_content 的NestedScrollView中match_parent 然后滚动将按您希望的那样完美平滑地进行。

仅供参考

<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:nestedScrollingEnabled="false"
            android:layout_height="wrap_content"
            android:clipToPadding="false" />

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

谢谢Micro,这是您的提示!

卡尔提克


1

所有答案的摘要(优点和缺点)

对于单个回收站视图

您可以在协调器布局中使用它。

优点 -它不会加载整个recyclerview项目。如此顺利加载。

坏处 -您不能在Coordinator布局中加载两个recyclerview-会产生滚动问题

参考 -https://stackoverflow.com/a/33143512/3879847

对于带有最少行的多个recylerview

您可以在NestedScrollView中加载

优势 -滚动流畅

缺点 -加载recyclerview的所有行,因此您的活动会延迟打开

参考-https://stackoverflow.com/a/33143512/3879847

对于具有大行(大于100)的多个recylerview

您必须使用recyclerview。

优势 -平滑滚动,平滑加载

缺点 -您需要编写更多代码和逻辑

在多视图持有者的帮助下将每个recylerview加载到主recyclerview中

例如:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

参考多viewHolder - https://stackoverflow.com/a/26245463/3879847


0

XML代码:

<android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clipToPadding="false" />

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

在Java代码中:

  recycleView = (RecyclerView) findViewById(R.id.recycleView);
     recycleView.setNestedScrollingEnabled(false);


0
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_main"
                android:layout_width="match_parent"
                android:layout_height="@dimen/layout_width_height_fortyfive"
                android:layout_marginLeft="@dimen/padding_margin_sixteen"
                android:layout_marginRight="@dimen/padding_margin_sixteen"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent">

                <TextView
                    android:id="@+id/textview_settings"
                    style="@style/textviewHeaderMain"
                    android:gravity="start"
                    android:text="@string/app_name"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/padding_margin_zero"
                android:layout_marginTop="@dimen/padding_margin_zero"
                android:layout_marginEnd="@dimen/padding_margin_zero"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/constraintlayout_main">

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recyclerview_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:nestedScrollingEnabled="false"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

        </android.support.constraint.ConstraintLayout>

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

</android.support.constraint.ConstraintLayout>

这段代码在ConstraintLayout android中工作


0

科特林

设置isNestedScrollingEnabledfalse每一个RecyclerView是滚动视图下

val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.isNestedScrollingEnabled = false

使用XML布局

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:nestedScrollingEnabled="false"
    android:layout_height="wrap_content" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.