RecyclView性能优化-妙用payload(有效载荷) 针对局部更新

· 有效负荷payloads用途

有效的避免RecyclView 不变部分 闪烁(尤其不变的部分也是RecyclView)。

· 有效负荷payloads详解

RecyclerView.Adapter 中有个带有 payloads 参数的函数,由于这个函数不是抽象函数,被很多人忽略了。

public void onBindViewHolder(VHholder, int position, List payloads) {
    onBindViewHolder(holder, position);
}
 
 

该函数的默认实现会调用 onBindViewHolder(holder, position) 这个抽象函数。
这个 payloads 参数是一个 List 对象,该对象不是 null 但可能是 空的。通过 Adapter 的 notifyXXX 函数的带有 payload 参数的函数可以设置 payload 对象,例如通知一个条目数据变化的函数:

public final void notifyItemChanged(int position, Object payload) {
    mObservable.notifyItemRangeChanged(position, 1, payload);
}

下面来看看这个 payload 是干什么的。

如果没有 payload , 当调用 notifyItemChanged 的时候, RecyclerView 会通过回调 onBindViewHolder(holder, position) 来更新当前数据变化的 View,但是对于比较复杂的条目,里面有很多个不同的控件,比如有图片、文字、CheckBox 等,用户点击一下当前条目(比如 喜欢一个微博信息),需要把喜欢的状态高亮。 也就是说,当前一个微博条目中只有一个喜欢状态的变化,但是需要重新在 onBindViewHolder(holder, position) 中设置所有View 的内容。对于每个 View ,当设置其内容的时候,都会触发 View 的重新布局和计算位置,这样至少一个 View 状态变化了 最终导致整个条目都需要重新布局一遍。

如果通过 payload 来告诉系统这个微博消息只有喜欢状态变化了,这样在调用 onBindViewHolder(VH holder, int position, List

需要注意的是,当 payloads 为 空的时候,说明是该条目的整个数据都变化了, 需要更新所有的数据,所以你可以在当 payloads 为 空 的时候调用不带 payloads 参数的函数,如下:

@Override
public void onBindViewHolder(ViewHolderholder, int position, List payloads) {
   if (payloads.isEmpty()) {
        // payloads 为 空,说明是更新整个 ViewHolder
        onBindViewHolder(holder, position);
   } else {
       // payloads 不为空,这只更新需要更新的 View 即可。
      holder.mBadgeView.setVisibility(((Item)payloads.get(0)).disabled ? View.VISIBLE : View.INVISIBLE);
   }
}
 
 

· 有效负荷payloads实践:

优化如下问题

如下图,实现数据的局部更新,并且500ms后还原颜色。


RecyclView性能优化-妙用payload(有效载荷) 针对局部更新_第1张图片
131672560794821790.png

正常处理如下:

1、接收到udp更新:setFlag(true) + notifyItemChanged(int position)
2、500ms后:setFlag(false) + notifyItemChanged(int position)

最近对这一块进行性能优化:
notifyItemChanged(int position, Object payload);//payload 有效载荷
主要代码如下:


    public final String PAYLOAD_CHANGE = "payloadChange";  //payload
    public final String PAYLOAD_RCOLOR = "payloadResumeColor";  //payload

    @Override
    public void onBindViewHolder(PriceListH holder, int position, 
                                 List payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        } else  {
            final String payload = payloads.get(0).toString(); 
            if(!TextUtils.isEmpty(payload)){
                if (TextUtils.equals(payload, PAYLOAD_CHANGE)) {
                    //... 此处省略代码 几百行
                } else if (TextUtils.equals(payload, PAYLOAD_RCOLOR )){
                    //... 此处省略代码 几十行
                }
            }
        }
    }

    @Override
    public void onBindViewHolder(PriceListH holder, int position) {
        /*
        ... 此处省略代码 几百行
        notifyItemChanged(int position);//正常处理
        if(isFalg()){
           //isFalgBug: 上下滑动,新滑出的item样式不是初始化的布局风格
        }else{
        }

        notifyItemChanged(int position, Object payload);//payload 有效载荷
        默认的初始化布局风格 ,没有isFalgBug

        * */
    }
 
 

补充:

//下拉刷新 清空部分数据(部分不变,避免RecyclView 不变部分 闪烁)
 if (hasData()) {
    int size = listdata.size();
   listdata.clear();
   adapter.notifyItemRangeRemoved(start,size);
}

//有新数据 添加(加载更多清空)
adapter.notifyItemRangeChanged(positionStart, itemCount, adapter.PAYLOAD_CHANGE);

.
纯纯代码兴味索然
感谢阅读收获归你
不妥之处敬请指教
QQ563084073
wbolin原创:https://www.jianshu.com/p/df69f8dfd118
.

RecyclView性能优化-妙用payload(有效载荷) 针对局部更新_第2张图片
加我微信

你可能感兴趣的:(RecyclView性能优化-妙用payload(有效载荷) 针对局部更新)