转自:Android recycleView 的一些优化与相关问题
recycleView 也出来很长时间了,记录一些自己见到的recycleView优化吧。
1.recyclerView.setHasFixedSize(true);
Item的高度是固定的,设置这个选项可以提高性能.总得来说就是就是避免整个布局绘制。就是避免requestLayout.
具体的可以看看stackoverflow的这个几个问题
Understanding RecyclerView setHasFixedSize
When do we use the recyclerView.setHasFixedSize?
设置这个可以避免重复的增删造成而外的浪费资源
看完就差不多了
2.复用RecycledViewPool
总而言之
如果RecycledView的adapter是一样的话可以考虑共享一个对象池。
比如说:
RecycledView嵌套RecycledView,里面的RecycledView大部分都adapter都一样。
转自图片
注意
如果 LayoutManager是LinearLayoutManager或其子类(如GridLayoutManager)
需要手动开启这个特性:layout.setRecycleChildrenOnDetach(true)
例如:
class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> {
RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();
...
@Override
public void onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView view = new RecyclerView(inflater.getContext());
LinearLayoutManager innerLLM = new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL);
innerLLM.setRecycleChildrenOnDetach(true);
innerRv.setLayoutManager(innerLLM);
innerRv.setRecycledViewPool(mSharedPool);
return new OuterAdapter.ViewHolder(innerRv);
}
...
3.横向嵌套RecyclerView滑动数据预加载,setInitialItemPrefetchCount
注意只适合横向嵌套
这里写图片描述
在内部的 LayoutManager 中调用 LinearLayoutManager 的setInitialItemPrefetchCount()方法(25.1版本起可用)
innerLLM.setInitialItemsPrefetchCount(num);
num值看自己列表定把。不是越大越好。比如列表展示刚刚展示四个半item。就设置5.以此类推吧
想了解具体的可以看看这篇文章
RecyclerView 数据预取
4.RecyclerView 预加载,getExtraLayoutSpace
一开始我做这个漫画预览界面的时候就要用到提前加载图片。上面那个嵌套的不管用,这里要吐槽一下百度,-v-!mmp这搜索都是一样的答案!!!!!!.最后还是在stack overflow上才找到方案。
只要增加预留的额外空间,就是改变滑动时预判的范围就可以了。
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
return 300;
}
};
具体的可以看看这两个
How to load all the images in the background of a RecyclerView in Android
使用getExtraLayoutSpace为LayoutManager设置更多的预留空间
5.特殊点的优化
如果你觉得你的内存还ok,也就是要RecyclerViews有个流畅的体验。可以考虑设置下面的几点
binding.fragmentCandidateBrowseList.setItemViewCacheSize(30);
binding.fragmentCandidateBrowseList.setDrawingCacheEnabled(true);
binding.fragmentCandidateBrowseList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
这里写图片描述
来自于下面这篇文章,就是如何达到60fps。里面一些优化也可以看看
RecyclerView Tips: How we achieved 60 FPS in Workable’s Android Recruiting App
6.RecycleView与NestedScrollView的嵌套
这是一个大坑,嵌套之后会发生一些奇奇怪怪的问题。
- 比如莫名的在中间显示(焦点被抢)
- RecycleView滑动会感觉到卡顿,可以通过mRecyclerView.setNestedScrollingEnabled(false);解决这个问题
- 一次性加载所有item,而不是加载当前可见的Item,如果你的item布局够复杂或者条目很多,卡顿会很严重
- 相关属性会失效,例如 linearManager.findLastVisibleItemPosition();获取当前第一个可见的position等…
相关问题链接与对应的解决方案:
- Recycler view inside NestedScrollView causes scroll to start in the middle
- Recyclerview inside Nested Scrollview scroll but does not fast scroll like normal Recyclerview or Nested Scrollview
3,和4.的话我是就没办法解决了,看了stackoverflow上的回答,就是最好别用嵌套。
这里写图片描述
7.RecycleView复杂布局相关建议
刚刚上面有说道,尽量少用嵌套,可以避免很多不必要的坑。如果布局复杂呢?一定要用到嵌套呢?
比如这个b站的这个直播布局
这里写图片描述
比较常见的布局上优化
- 减少布局的嵌套,减少布局层次关系
- <include>,<merge>,<ViewStub>等标签
多类型,多布局
按照平常的思维,编写上面的布局,一般情况是这样子的。
这样做是Ok的,但是随着业务的增长,东西都堆积在一个 Adapter,所以会变得繁琐,不好维护。
我一般是通过这种多布局的方式去处理,把不用的业务分发到不同的viewHolder.
所以我这边推荐我自认为还是ok的框架,小,且强大。
网友评论