RecyclerView优化-滚动性能改进
Banner Recyclerview优化滚动性能改进
在此博客中,我们将学习如何优化Android中的RecyclerView性能。通过这些优化,我们可以使RecyclerView滚动平滑。
当我们在Android应用程序中实现RecyclerView时,有时会遇到类似以下问题:RecyclerView项滚动不流畅。由于我们的Android应用似乎很落后,因此会导致糟糕的用户体验。
让我们看看我们可以做些什么来提高RecyclerView的性能,从而获得流畅的滚动。
RecyclerView优化技术
让我们开始吧
使用图像加载库
由于垃圾回收(GC)在主线程上运行,导致UI不响应的原因之一是内存的连续分配和释放,这导致GC运行非常频繁。通过使用位图池概念,我们可以避免这种情况。
最好的部分是像Glide,Fresco这样的图像加载库使用此位图池概念。因此,请始终使用图像加载库。
将所有与图像有关的任务委托给这些库。
设置图像的宽度和高度
如果我们的图像宽度和高度是动态的(不固定),并且我们正在imageUrl从服务器获取。
如果我们事先未设置正确的图像宽度和高度,则在加载(下载图像)和将图像设置到ImageView的过渡过程中,UI会闪烁(实际上在下载完成时使其可见)。
因此,我们应该要求后端开发人员发送图像尺寸或宽高比,因此,我们可以计算所需的ImageView宽度和高度。
然后,我们将只能预先设置宽度和高度。因此没有闪烁。问题解决了!
在onBindViewHolder方法中少做些
缩图图片
我们的onBindViewHolder方法应该做的工作很少。我们应该检查我们的onBindViewHolder方法并对其进行优化。通过这样做,我们可以看到RecyclerView的改进。
使用通知商品RecyclerView API
每当我们有删除,更新,添加商品的用例时,请使用Notify Item API。
adapter.notifyItemRemoved(position)
adapter.notifyItemChanged(position)
adapter.notifyItemInserted(position)
adapter.notifyItemRangeInserted(start, end)
另外,检查DiffUtil。
如果被迫notifyDataSetChanged()根据用例使用,可以尝试使用setHasStableIds(true)。
adapter.setHasStableIds(true)
它指示是否可以用Long类型的唯一标识符表示数据集中的每个项目。
即使调用notifyDataSetChanged(),它也不必处理整个适配器的完整重新排序,因为它可以查找某个位置的项目是否与以前相同,并且可以减少工作量。
避免嵌套视图
如果可能,我们应避免使用嵌套视图,并尽可能尝试创建平面视图。嵌套会降低RecyclerView的性能。平面视图提高了性能。
使用setHasFixedSize
如果所有项目的高度相等,则应使用此方法。添加以下内容并检查性能。
recyclerView.setHasFixedSize(true)
使用setRecycledViewPool优化嵌套的RecyclerView
我们知道,RecyclerView尽可能遵循“使用池重用视图”的原理。
检查RecyclerView在内部如何工作?
如果我们有嵌套RecyclerView的用例。
- OuterRecyclerView
- InnerRecyclerViewOne
- InnerRecyclerViewTwo
但是默认情况下,该优化适用于该特定的RecyclerView,因为该特定的RecyclerView具有自己的视图池。
具有相同视图类型的两个RecyclerView之间不会共享该池。
因此,我们可以做的是创建一个单个ViewPool并将其传递给所有内部RecyclerViews,以使其共享,如下所示:
class OuterRecyclerViewAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
// code removed for brevity
private val viewPool = RecyclerView.RecycledViewPool()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// code removed for brevity
viewHolderOne.innerRecyclerViewOne.setRecycledViewPool(viewPool)
// code removed for brevity
viewHolderTwo.innerRecyclerViewTwo.setRecycledViewPool(viewPool)
}
// code removed for brevity
}
这将提高滚动性能,因为它将开始重用共享ViewPool中的视图。
使用setItemViewCacheSize
我们可以尝试通过设置ItemView控件缓存大小。
recyclerView.setItemViewCacheSize(cacheSize)
根据官方文档:它设置在将屏幕外视图添加到潜在共享的回收视图池之前保留的屏幕外视图的数量。屏幕外视图高速缓存始终了解连接的适配器中的更改,从而允许LayoutManager重用那些未经修改的视图,而无需返回适配器重新绑定它们。
这意味着,当我们滚动RecyclerView使得只有一个几乎完全不在屏幕外的视图时,RecyclerView会将其保持在原处,以便我们可以将其滚动回到视图中而不必onBindViewHolder()再次调用它。
通常,我们不会更改视图缓存的大小,但可以尝试一下,如果适合您,请实施它。
这些都是我们可以做的,以提高RecyclerView的性能。现在就这样。