Android~RecycleView优化

一、RecycleView更新Item闪烁

项目中有Recycle更新部分item的需求,发现item居然闪烁了,给用户体验不是很好。回想QQ微信中也聊天列表也没出现这么长时间的闪烁,好奇它背后是怎么做到的,于是便查了一下,原来RecycleView onBindViewHolder重复调用,新的holder替换旧的holder替换存在一个过渡动画,这样就导致了闪烁。
知道原因了也就有解决方法:

法1.

去除itemAnimator

recyclerView.setItemAnimator(null);
法2

将动画关闭,动画时间设置为0。这个方法不是很管用,只针对单个item还是OK的。但如果是多个item,实际测试还是会出现快速的闪烁一下,建议使用法1。

recyclerView.getItemAnimator().setAddDuration(0);
recyclerView.getItemAnimator().setChangeDuration(0);
recyclerView.getItemAnimator().setMoveDuration(0);
recyclerView.getItemAnimator().setRemoveDuration(0);
((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

二、RecycleView好伴侣DiffUtil使用

参考: 【Android】RecyclerView的好伴侣:详解DiffUtil
首先DiffUtil是RecycleView自带的一个工具类,无需引入新的库。它帮我自动自动计算新老数据集的差异,并根据差异情况自动调用notifyItemRangeInserted notifyItemRangeRemoved notifyItemMoved notifyItemRangeChanged这四个方法,这样我们就不需要无脑的调用notifyDataSetChanged方法了。

使用步骤:

1、使用自己的实体类,实现HomeDeviceDiff

import androidx.recyclerview.widget.DiffUtil;

import com.hynson.entity.HomeDevice;

import java.util.List;

public class HomeDeviceDiff extends DiffUtil.Callback {
    private List<HomeDevice> oldDatas,newDatas;

    public HomeDeviceDiff(List<HomeDevice> oldDatas, List<HomeDevice> newDatas) {
        this.oldDatas = oldDatas;
        this.newDatas = newDatas;
    }

    @Override
    public int getOldListSize() {
        return oldDatas != null ? oldDatas.size() : 0;
    }

    @Override
    public int getNewListSize() {
        return newDatas != null ? newDatas.size() : 0;
    }

    @Override
    public boolean areItemsTheSame(int oldPos, int newPos) {
        HomeDevice oldBean = oldDatas.get(oldPos);
        HomeDevice newBean = newDatas.get(newPos);

        return oldBean.getId().equals(newBean.getId()) && oldBean.getDevType().equals(newBean.getDevType())
                && oldBean.getTitle().equals(newBean.getTitle()) && oldBean.getState().equals(newBean.getState())
                && oldBean.getWorkState().equals(newBean.getWorkState()) && oldBean.getStateTip().equals(newBean.getStateTip());
    }

    @Override
    public boolean areContentsTheSame(int oldPos, int newPos) {
        HomeDevice oldBean = oldDatas.get(oldPos);
        HomeDevice newBean = newDatas.get(newPos);

        return oldBean.getId().equals(newBean.getId()) && oldBean.getDevType().equals(newBean.getDevType())
                && oldBean.getTitle().equals(newBean.getTitle()) && oldBean.getState().equals(newBean.getState())
                && oldBean.getWorkState().equals(newBean.getWorkState()) && oldBean.getStateTip().equals(newBean.getStateTip());
    }
}

2、在我们更新适配器的地方,调用如下代码

DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new HomeDeviceDiff(mView.getHomeDeviceAdapter().getmDeviceList(), devices), true);
diffResult.dispatchUpdatesTo(mView.getHomeDeviceAdapter());
mView.getHomeDeviceAdapter().updateData(devices);

猜你喜欢

转载自blog.csdn.net/Bluechalk/article/details/108428048