ScrollView 内的 Recyclerview 滚动不流畅
Recyclerview inside ScrollView not scrolling smoothly
对于我的应用程序,我在 ScrollView
中使用 RecyclerView
,其中 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));
ScrollView
中的RecyclerView
:
<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" />
尝试做:
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 >
我只需要用这个:
mMyRecyclerView.setNestedScrollingEnabled(false);
在我的 onCreateView()
方法中。
非常感谢!
我有类似的问题(我试图创建一个嵌套的 RecyclerViews,类似于 Google PlayStore 设计)。处理这个问题的最好方法是子类化 RecyclerViews 并覆盖 'onInterceptTouchEvent' 和 'onTouchEvent' 方法。这样您就可以完全控制这些事件的行为方式并最终滚动。
你也可以这样使用:
将此行添加到您的 recyclerView xml 文件中:
android:nestedScrollingEnabled="false"
或在 java 代码中:
RecyclerView.setNestedScrollingEnabled(false);
希望这对您有所帮助。
您可以尝试使用 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);
如果您在子视图中使用 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,这是您的提示!
卡尔提克
使用嵌套滚动视图代替滚动视图解决了我的问题
<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>
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);
或者您可以在回收站视图中设置android:focusableInTouchMode="true"
<?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
所有答案的总结(优点和缺点)
对于单个recyclerview
您可以在 Coordinator 布局中使用它。
优点 - 它不会加载整个 recyclerview 项目。这么顺利加载。
缺点 - 你不能在 Coordinator 布局中加载两个 recyclerview - 它会产生滚动问题
参考 -
对于具有最少行的多个 recylerview
您可以在 NestedScrollView 中加载
优点 - 滚动流畅
缺点 - 它会加载 recyclerview 的所有行,因此您的 activity 打开会延迟
参考 -
对于大行(超过 100)的多个 recylerview
你必须使用 recyclerview。
优点 - 滚动流畅,加载流畅
缺点 - 你需要写更多的代码和逻辑
在 multi-viewholders
的帮助下将每个 recylerview 加载到主 recyclerview 中
例如:
MainRecyclerview
-ChildRecyclerview1 (ViewHolder1)
-ChildRecyclerview2 (ViewHolder2)
-ChildRecyclerview3 (ViewHolder3)
-Any other layout (ViewHolder4)
参考 multi-viewHolder -
用 NestedScrollView 替换 ScrollView 导致平滑滚动到底部。
科特林
将滚动视图下的每个 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" />
这里的答案都是一样的。我已经使用了每个人的建议。然后我发现 NestedScrollView 比 ScrollView 快所以
使用
<androidx.core.widget.NestedScrollView
而不是
<ScrollView
照常使用
recycleView.setNestedScrollingEnabled(false);
简单 将此行添加到您的 JAVA class
list.setNestedScrollingEnabled(false);
我自己也遇到过这个问题,scrollview 中有一个 recycler view,而且滚动似乎不流畅。我的问题的原因是在回收站视图之上有滚动视图,这不是我的要求所需要的。所以在我删除滚动视图并为回收视图添加 android:scrollbars="vertical"
之后,滚动很流畅。
经过 3 天的研究,我解决了项目中的平滑滚动问题。
问题是 <layer-list>
可绘制对象设置在 item_user.xml
文件的背景中,因此渲染需要 GPU 时间 这就是滚动不流畅的原因。所以请不要在适配器项目的背景中使用复杂的 <layer-list>
drawable。
我的问题已通过上述解决方案解决,以下选项对我没有用
- setNestedScrollingEnabled
- setHasFixedSize
- setItemViewCacheSize
对于我的应用程序,我在 ScrollView
中使用 RecyclerView
,其中 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));
ScrollView
中的RecyclerView
:
<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" />
尝试做:
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 >
我只需要用这个:
mMyRecyclerView.setNestedScrollingEnabled(false);
在我的 onCreateView()
方法中。
非常感谢!
我有类似的问题(我试图创建一个嵌套的 RecyclerViews,类似于 Google PlayStore 设计)。处理这个问题的最好方法是子类化 RecyclerViews 并覆盖 'onInterceptTouchEvent' 和 'onTouchEvent' 方法。这样您就可以完全控制这些事件的行为方式并最终滚动。
你也可以这样使用:
将此行添加到您的 recyclerView xml 文件中:
android:nestedScrollingEnabled="false"
或在 java 代码中:
RecyclerView.setNestedScrollingEnabled(false);
希望这对您有所帮助。
您可以尝试使用 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);
如果您在子视图中使用 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,这是您的提示!
卡尔提克
使用嵌套滚动视图代替滚动视图解决了我的问题
<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>
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);
或者您可以在回收站视图中设置android:focusableInTouchMode="true"
<?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
所有答案的总结(优点和缺点)
对于单个recyclerview
您可以在 Coordinator 布局中使用它。
优点 - 它不会加载整个 recyclerview 项目。这么顺利加载。
缺点 - 你不能在 Coordinator 布局中加载两个 recyclerview - 它会产生滚动问题
参考 -
对于具有最少行的多个 recylerview
您可以在 NestedScrollView 中加载
优点 - 滚动流畅
缺点 - 它会加载 recyclerview 的所有行,因此您的 activity 打开会延迟
参考 -
对于大行(超过 100)的多个 recylerview
你必须使用 recyclerview。
优点 - 滚动流畅,加载流畅
缺点 - 你需要写更多的代码和逻辑
在 multi-viewholders
的帮助下将每个 recylerview 加载到主 recyclerview 中例如:
MainRecyclerview
-ChildRecyclerview1 (ViewHolder1) -ChildRecyclerview2 (ViewHolder2) -ChildRecyclerview3 (ViewHolder3) -Any other layout (ViewHolder4)
参考 multi-viewHolder -
用 NestedScrollView 替换 ScrollView 导致平滑滚动到底部。
科特林
将滚动视图下的每个 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" />
这里的答案都是一样的。我已经使用了每个人的建议。然后我发现 NestedScrollView 比 ScrollView 快所以
使用
<androidx.core.widget.NestedScrollView
而不是
<ScrollView
照常使用
recycleView.setNestedScrollingEnabled(false);
简单 将此行添加到您的 JAVA class
list.setNestedScrollingEnabled(false);
我自己也遇到过这个问题,scrollview 中有一个 recycler view,而且滚动似乎不流畅。我的问题的原因是在回收站视图之上有滚动视图,这不是我的要求所需要的。所以在我删除滚动视图并为回收视图添加 android:scrollbars="vertical"
之后,滚动很流畅。
经过 3 天的研究,我解决了项目中的平滑滚动问题。
问题是 <layer-list>
可绘制对象设置在 item_user.xml
文件的背景中,因此渲染需要 GPU 时间 这就是滚动不流畅的原因。所以请不要在适配器项目的背景中使用复杂的 <layer-list>
drawable。
我的问题已通过上述解决方案解决,以下选项对我没有用
- setNestedScrollingEnabled
- setHasFixedSize
- setItemViewCacheSize