ScrollView内的Recyclerview无法顺利滚动

时间:2015-10-15 08:27:07

标签: android android-recyclerview android-scrollview android-scroll

对于我的应用,我在RecyclerView内使用ScrollView,其中RecyclerView的高度基于其内容使用this library。滚动工作正常,但当我滚动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));

RecyclerView中的ScrollView

<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" />

17 个答案:

答案 0 :(得分:344)

尝试做:

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 >

然而,这是一条较长的路要走,如果您对自定义线性布局管理器没问题,那么只需在回收站视图上禁用嵌套滚动。

编辑(2016年4月3日)

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

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

答案 1 :(得分:71)

我只需要使用它:

mMyRecyclerView.setNestedScrollingEnabled(false);

在我的onCreateView()方法中。

非常感谢!

答案 2 :(得分:25)

您可以这样使用:

将此行添加到recyclerView xml:

android:nestedScrollingEnabled="false"

或在java代码中:

RecyclerView.setNestedScrollingEnabled(false);
希望这会有所帮助。

答案 3 :(得分:8)

您可以尝试使用XML和编程方式。但是,您可能遇到的问题(在API 21之下)通过XML执行它将无法正常工作。所以最好在Activity / Fragment中以编程方式设置它。

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);

答案 4 :(得分:2)

我有类似的问题(我试图创建一个嵌套的RecyclerViews像Google PlayStore设计)。解决这个问题的最好方法是通过子类化子级RecyclerViews并覆盖&#39; onInterceptTouchEvent&#39;和&#39; onTouchEvent&#39;方法。通过这种方式,您可以完全控制这些事件的行为并最终滚动。

答案 5 :(得分:2)

使用嵌套滚动视图代替滚动视图解决了我的问题

<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>

答案 6 :(得分:0)

经过 3 天的研究,我解决了项目中的平滑滚动问题。

问题是在 <layer-list> 文件的背景中设置了 item_user.xml drawable,因此需要 GPU 时间来渲染,这就是滚动不流畅的原因。所以请不要在适配器项的背景中使用复杂的 <layer-list> drawable。

我的问题已通过上述解决方案解决,以下选项对我没有用

  1. setNestedScrollingEnabled
  2. setHasFixedSize
  3. setItemViewCacheSize

答案 7 :(得分:0)

我自己也遇到过这个问题,滚动视图中有一个回收器视图,并且滚动似乎不流畅。我的问题的原因是在我的要求不需要的回收器视图顶部有滚动视图。因此,在我删除了滚动视图并为回收站视图添加了 android:scrollbars="vertical" 之后,滚动变得流畅了。

答案 8 :(得分:0)

简单地将此行添加到您的JAVA类中

list.setNestedScrollingEnabled(false);

答案 9 :(得分:0)

每个答案都是相同的。而且我已经使用了每个人的建议。然后我发现NestedScrollView比ScrollView快

使用

<androidx.core.widget.NestedScrollView

代替

<ScrollView

并像往常一样使用它

recycleView.setNestedScrollingEnabled(false);

答案 10 :(得分:0)

科特林

为滚动视图下的每个RecyclerView将isNestedScrollingEnabled设置为false

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" />

答案 11 :(得分:0)

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

答案 12 :(得分:0)

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

对于单个回收站视图

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

优势 -它不会加载整个recyclerview项目。加载非常顺畅。

缺点 -您不能在协调器布局中加载两个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)

有关multi-viewHolder的参考-https://stackoverflow.com/a/26245463/3879847

答案 13 :(得分: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中有效

答案 14 :(得分:0)

或者您也可以在回收者视图中设置android:focusableInTouchMode="true"

答案 15 :(得分:0)

XML代码:

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

在Java代码中:

try:
    cur.execute("select IP_ADD,VENDOR,DVC_ROLE,CIRCLE,SSA,REGION from DVC_SUMMARY_DATA where IP_ADD in (%s);" % ip_i)

except Exception as e:
    print("error while fetching details " + str(e))

result_i = cur.fetchall()

try:
    cur.execute("select IP_ADD,VENDOR,DVC_ROLE,CIRCLE,SSA,REGION from DVC_SUMMARY_DATA where IP_ADD in (%s);" % ip_n)

except Exception as e:
    print("error while fetching details " + str(e))

result_n = cur.fetchall()

try:
    cur.execute("select IP_ADD,VENDOR,DVC_ROLE,CIRCLE,SSA,REGION from DVC_SUMMARY_DATA where IP_ADD in (%s);" % ip_c)

except Exception as e:
    print("error while fetching details " + str(e))

result_c = cur.fetchall()

try:
    cur.execute("select IP_ADD,VENDOR,DVC_ROLE,CIRCLE,SSA,REGION from DVC_SUMMARY_DATA where IP_ADD in (%s);" % ip_b)

except Exception as e:
    print("error while fetching details " + str(e))

result_b = cur.fetchall()

答案 16 :(得分:0)

如果您在子视图中使用VideoView或重量级小部件,请使RecyclerView的高度为wrap_content 高度为match_parent的NestedScrollView内部 然后滚动就可以按需要完美平滑地工作。

仅供参考,

    <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,这是您的提示

karthik