RecyclerView 局部刷新

2,258 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

RecyclerView 局部刷新

RecyclerView 从安卓5.0系统开始,到现在已经有好几年的时间,大家慢慢的也从ListView转为RecyclerView,使用了RecyclerView才会觉得还是RecyclerView香,搭配着万能适配器一起用,非常简洁的代码就能实现一个列表,而且拓展性灵活性也要高不少。这篇文章主要讲RecyclerView的局部刷新。

为什么需要局部刷新

全部数据刷新很方便,直接调用notifyDataSetChanged() 方法就可以了,但是全部刷新从性能上会有损失,因为全部刷新是将数据循环刷新,当数据量很多时,如果有局部刷新,就可以节约很多性能了。

怎么实现局部刷新

添加数据

在某个索引处添加数据

public final void notifyItemInserted(int position)

批量添加(起始索引位置,修改数量)

public final void notifyItemRangeInserted(int positionStart, int itemCount)

删除数据

移除某个索引处的数据

public final void notifyItemRemoved(int position)

批量删除(起始索引位置,修改数量)

public final void notifyItemRangeRemoved(int positionStart, int itemCount)

更新数据

更新某个索引处的数据

public final void notifyItemChanged(int position) 

批量更新(起始索引位置,修改数量)

public final void notifyItemRangeChanged(int positionStart, int itemCount)

Item中更新部分组件

更新Item数据固然简单,但是可以仅仅更新Item中的单个组件吗?

因为更新完整Item时,Item中的图片会重新加载,会出现闪烁的情况。

那么可以仅仅只更新单个组件吗? 答案是肯定的。

这就需要我们使用notifyItemChanged(int position, @Nullable Object payload)方法,并且在ViewHolder中进行逻辑判断,因为需要程序需要你指定Item中局部更新的逻辑。

Bundle payload = new Bundle();
payload.putString("KEY_NAME", mDatas.get(1).getName());
personAdapter.notifyItemChanged(position, payload);

在适配器中

@Override
public void onBindViewHolder(DiffVH holder, int position, List<Object> payloads) {
    if (payloads.isEmpty()) {
        onBindViewHolder(holder, position);
    } else {
        Bundle payload = (Bundle) payloads.get(0);
        PersonInfo bean = mDatas.get(position);
        for (String key : payload.keySet()) {
            switch (key) {
                case "KEY_INDEX":
                    holder.tv_index.setText(String.valueOf(bean.getIndex()));
                    break;
                case "KEY_NAME":
                    holder.tv_name.setText(String.valueOf(bean.getName()));
                    break;
                default:
                    break;
            }
        }
    }
}

2020.10.20 更新:评论区有掘友提到了DiffUtils,下篇文章接着探寻。