这更像是一个通用的问题,但经过大量的搜索和尝试后,我无法理解为什么这么难实现。 This是我能找到的最接近的答案,但仍无法实施。
具体来说我正在使用RecyclerView和GridLayoutManager。我想要的是平滑滚动的网格布局(如默认的gallary应用程序),没什么特别的,但是网格布局管理器的默认实现是在一个“生涩的”中滚动视图。方式。我尝试从上面的链接实现该方法,但没有成功。
我也试过实现LinearSmoothScroller,但我不确定如何实现computeScrollVectorForPosition方法。 computeScrollVectorForPosition上的Google's documentation字面上有0个字。
我找到了this 3 part tutorial,但它的帮助很小。所以,我想问的是:我们可以在LinearSmoothScroller中实现某种模板代码,还是扩展RecyclerView.SmoothScroller并实现平滑滚动?即使代码依赖于gridlayout中每行的项目数和项目数,也必须有一些方法可以轻松完成。我在这里错过了什么吗?
答案 0 :(得分:31)
"生涩"的典型来源在Android中滚动是应用程序在更新UI的主应用程序线程上花费了太多时间。对于RecyclerView
,这意味着在onBindViewHolder()
或可能在onCreateViewHolder()
中花费太多时间。每个都需要以亚毫秒的速度返回,这意味着您无法在其中执行磁盘I / O或网络I / O.
认为我发现了问题。我正在使用holder.photo.setImageBitmap(BitmapFactory.decodeFile(itemList.get(position).get AbsolutePath())); onBindViewHolder()和图像文件大约100kb,列表中有大约十几个图像
是的,那将在主应用程序线程上进行磁盘I / O和图像解码。这将足够慢,导致UI中的jank(即"生涩"滚动)。
考虑使用图像加载库,如Picasso或Universal Image Loader,因为它们可以异步地从位图填充ImageView
。
This sample app使用通用图片加载器来帮助填充RecyclerView
(带GridLayoutManager
)的内容,数据源是设备上的可用视频。
答案 1 :(得分:30)
在您RecyclerView
或Activity
Fragment
的任何地方添加此项
RecyclerView mRecyclerview = (RecyclerView) findViewById(...);
mRecyclerview.setNestedScrollingEnabled(false);
setNestedScrollview(false)
为你做的工作。
答案 2 :(得分:11)
我刚遇到这个问题,并禁用嵌套滚动修复它。 这样做:
yourRecyclerview.setNestedScrollingEnabled(false);
或者您可以更改定义RecyclerView的xml文件中的值:
<android.support.v7.widget.RecyclerView
android:id="@+id/yourRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"/>
答案 3 :(得分:2)
我刚遇到这个问题,我得到了
我将RecyclerView
放在ScrollView
中
因此,请切勿将RecyclerView
放入可能引起问题的ScrollView
内。
mLayoutManager.findFirstVisibleItemPosition()
那总是返回一个固定值。还要检查
recyclerview.setNestedScrollingEnabled(false);
答案 4 :(得分:1)
android:animateLayoutChanges="false"
答案 5 :(得分:1)
我通过覆盖calculateSpeedPerPixel(DisplayMetrics displayMetrics)
方法使滚动变得平滑:
public class CustomLayoutManager extends LinearLayoutManager {
protected CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private class CenterSmoothScroller extends LinearSmoothScroller {
CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 0.5f; //pass as per your requirement
}
}
}
答案 6 :(得分:0)
您需要使用“ Picasso”库异步加载图像,并使用fit()
函数确保所加载图像的大小与布局中图像视图的大小相似。 。另外,如果您在滚动视图中使用回收站视图,请确保将nested scrolling
设置为false。
我通过以上三种方法解决了问题
答案 7 :(得分:0)
使用库,如此处其他评论所述。还要确保您没有在Scrollview中嵌套Recyclerviews。这就是为什么我的以前不那么顺畅的原因之一。
答案 8 :(得分:0)
在里面花了 3 天后,我解决了项目中的平滑滚动问题。
问题在于 <layer-list>
文件的背景中设置了 item_user.xml
drawable,因此需要 GPU 时间来渲染,这就是滚动不流畅的原因。
不要在适配器项中使用 <layer-list>
或任何其他复杂的 drawable。
答案 9 :(得分:-1)
只需添加此
animateLayoutChanges = true
在recyclerview xml中