NestedScrollView 嵌套RecyclerView 加载大量数据卡顿

围巾🧣 2024年05月07日 362次浏览

现状

当你把 RecyclerView 放在 NestedScrollView 里,就可能会发现性能出现问题。

因为当 NestedScrollView 包含的 RecyclerView 加载大量数据时,onCreateViewHolder() 方法会被多次调用,导致应用在启动时会有一段时间的冻结。

RecyclerView 最大的优点之一是内部的视图复用,这样可以在内存和流畅性方面实现很好的优化。但是一旦将 RecyclerView 嵌套在 NestedScrollView 中,RecyclerView 的内容会一次性加载完毕,无法实现视图的复用。当数据量很大时,肯定是卡到爆炸

优化方案

最好的方案是 去掉 NestedScrollView,不过是改用headerView 或者 footerView 的方式添加头部尾部内容

技巧

  • RecyclerView的优化技巧
    • 使用 RecyclerView 的 ViewHolder 模式来重用视图,以减少视图的创建和销毁次数。
    • 使用合适的布局管理器(LayoutManager),如 LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager,以确保只有在屏幕上可见的部分才会被实际渲染。
    • 使用分页加载或增量加载,而不是一次性加载所有数据。
  • 避免嵌套滚动
    • 尽量避免在 NestedScrollView 中嵌套 RecyclerView,特别是在数据量很大的情况下。
    • 考虑直接使用 RecyclerView,并根据需要实现自定义的滚动效果。
  • 使用其他布局容器
    • 如果可能的话,尝试使用其他布局容器替代 NestedScrollView,例如 ConstraintLayoutLinearLayout,并确保视图层次结构的简单性。
  • 异步加载和优化数据加载
    • 使用异步加载机制,例如使用 AsyncTask、 或者 Kotlin 协程等,在后台线程中加载数据,以保持 UI 的流畅性。
    • 如果可能,对数据进行优化,以减少加载时间和内存占用。
  • 使用列表头部或尾部的占位符
    • RecyclerView 中,可以考虑添加头部或尾部的占位符视图,以避免整个列表在数据加载完毕前频繁的动态改变尺寸。
  • 使用合适的缓存策略
    • 如果数据是不经常变化的,可以考虑实现合适的缓存策略,以减少不必要的数据重复加载。