Recycler View 性能优化 (你必须知道的几点)

先来对比一下 :ListView 与 RecyclerView

ViewHolder

基本原理 :使不使用 ViewHolder 都在复用 convertView ,

区别,是 findViewById 的性能节省。

ListView 缓存机制

在这里插入图片描述

在这里插入图片描述

  • Active View

在 Active View 中的item ,在滑动过程中,

listView 自动帮我们复用了,不会再走getView()方法

凡是调用了 getView() 视图都需要重新绑定。

  • Scrap View

Scrap View 中的数据都是“脏”的,都需要走getView() 方法

RecyclerView 缓存机制

在这里插入图片描述

在这里插入图片描述

四层缓存
前两层,Scrap 和 Cache 数据都是干净的,都可以拿来直接用。
第三层,ViewCacheExtension 是用户自定义的缓存策略
第四层,RecycledViewPool 数据时‘’ ,不走 onCreateViewHolder,但是需要重新绑定会走 onBindViewHolder 方法

在这里插入图片描述

在这里插入图片描述

RecyclerView 可能不知道的 性能优化策略

1、不要将 view 的 setOnClickListener(new View.OnClickListener()) 写在 OnBindView中,这样会频繁创建,尽量写在 onCreateViewHolder 中(但是处理逻辑就会有些麻烦 if/else, switch等 )

2、LinearLayoutManager.setInitialPrefetchItemCount() 预加载的数量,避免一些交复杂的布局,突然滑入屏幕显示的时候出现问题()

横向列表初次显示时可见的 Item 个数

PS :只有 LinearLayoutManager 有这个 API;

​ 只有嵌套在内部的 RecyclerView 才会生效

3、RecyclerView.setHasFixedSize(); (在recyclerView 数据变化 但是大小 不变的情况下,可以使用)

作用是:mHasFixedSize 为 true 时,回重新摆放 变化的 childLayout,不重新摆放所有布局(走 requestLayout方法)

void triggerUpdateProcessor() {
    if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
        ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);
    } else {
        mAdapterUpdateDuringMeasure = true;
        requestLayout();
    }
}

4、RecycledViewPool 缓存池 (根据 viewType 进行缓存)

比如:下面多列表的情况,可能多个 Rv 使用了相同的 viewType , 那么他们就可以 共享 缓存池

看下源码注释

RecycledViewPool lets you share Views between multiple RecyclerViews.

If you want to recycle views across RecyclerViews, create an instance of RecycledViewPool and use {@link RecyclerView#setRecycledViewPool(RecycledViewPool)}.

RecyclerView automatically creates a pool for itself if you don’t provide one.

大概意思:

RecycledViewPool使您可以在多个RecyclerView之间共享视图。

如果要在RecyclerViews中回收视图,请创建RecycledViewPool实例,然后使用{@link RecyclerView#setRecycledViewPool(RecycledViewPool)}。

如果您不提供一个池,RecyclerView会自动为其自动创建一个池。

如何使用:
  • 开启这一项支持

    需要注意的是,如果你使用的LayoutManager是LinearLayoutManager或其子类(如GridLayoutManager),需要手动开启这个特性:
    
    layout.setRecycleChildrenOnDetach(true)
    

在这里插入图片描述

在这里插入图片描述

DiffUtil 增量更新(提升列表性能)
DiffUtil .Callback (这是一个,给系统看的 callback,用于计算 diff 的 )
一共有5个方法:

在这里插入图片描述

在这里插入图片描述

下面 3 个方法 的返回值关系,以及执行顺序是

在这里插入图片描述

在这里插入图片描述

可以不实现 getChangePayload 方法,但是这样就不能看到RV 的增量更新了

在这里插入图片描述

如何 在adapter 中使用 :
在这里插入图片描述

这时候 发现 getChangePayload 中 返回的 payload 并没有被使用,在 adapter 中有一个 带 payloads 参数的 onBindViewHolder 重载方法, 他做的事就是 局部绑定

    @Override
    public void onBindViewHolder(@NonNull DemoViewHolder holder, int position, @NonNull List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
        
    }

在这里插入图片描述

DiffUtil 的效率
在列表很大的时候计算 Diff ,计算可能会导致掉帧(>60ms)。
google 的推荐方法是 在列表很大的时候 【异步计算】 Diff

在这里插入图片描述

为什么 ItemDecoration 可以绘制分隔线?
ItemDecoration 还能做什么事情?
  • 分割线
    请自行脑补。。。

  • 高亮

在这里插入图片描述

  • 将item 进行分组

在这里插入图片描述

关于 RecyclerView 更多的扩展

可以看一下这个网址:

https://advancedrecyclerview.h6ah4i.com/swipeable/tutorial/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值