繁体   English   中英

(android) 我可以在我的 DiffUtill 实现中使用此代码吗?

[英](android) Can I use this code in my DiffUtill implementation?

我现在正在制作DiffUtil class 以仅更新RecyclerView中更改的项目。

我看过其他几个示例代码。

在比较两个对象时,他们比较了唯一值,例如在areItemsTheSame()中的Model(Data) class 中定义的 id。

但是,我认为很难为 List 分配一个idunique value ,或者代码很乱。

我必须像这样定义和比较id吗?

我真的需要在Model class中定义一个唯一的 Id 变量来分隔每个 object 吗? 或者我不应该简单地使用equals()吗?

用这个不就是比较object的地址,还要比较object的内容吗?

作为一个附加问题

DiffUtil.CallBackDiffUtil.ItemCallBack什么区别?

这是我的代码。

例程Model.java

public class RoutineModel {
    private ArrayList<RoutineDetailModel> routineDetailModels;
    private String routine;

    public RoutineModel(ArrayList<RoutineDetailModel> items, String routine) {
        this.routine = routine;
        this.routineDetailModels = items;
    }

    public ArrayList<RoutineDetailModel> getDetailItemList() {
        return routineDetailModels;
    }

    public int getDetailItemSize() {
        return routineDetailModels.size();
    }

    public String getRoutine() {
        return routine;
    }

    public void setRoutine(String routine) {
        this.routine = routine;
    }
}

例程DiffUtil.java

public class RoutineDiffUtil extends DiffUtil.Callback {
    private final List<RoutineModel> oldRoutineList;
    private final List<RoutineModel> newRoutineList;

    public RoutineDiffUtil(ArrayList<RoutineModel> oldRoutineList, ArrayList<RoutineModel> newRoutineList) {
        this.oldRoutineList = oldRoutineList;
        this.newRoutineList = newRoutineList;
    }

    @Override
    public int getOldListSize() {
        return oldRoutineList.size();
    }

    @Override
    public int getNewListSize() {
        return newRoutineList.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldRoutineList.equals(newRoutineList);
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        return oldRoutineList.equals(newRoutineList);
    }
}

你弄错了areItemsTheSame()areContentsTheSame()回调的含义。 如您所见,其中有oldItemPositionnewItemPosition arguments。 您应该使用它们来比较特定项目——而不是列出它们本身。

In areItemsTheSame() you have to check whether model at "old" position in the old list equals a model at "new" position in the new list . 这就是 DiffUtil 知道它是否必须制作重新排序动画的方式。

当且仅当您在上一个回调中为它们返回true时,才会为两个项目调用areContentsTheSame() 在这里,您必须检查“旧”和“新”模型的视觉表示是否相同。 这就是 DiffUtil 知道它是否必须制作“项目更改”动画的方式。

要比较两个模型,您必须覆盖equals()hashCode() 在那里您指定您认为两个模型相同的条件。 例如,如果他们有相同的routine 我不知道你的任务的上下文,所以我不能确切地告诉你如何实现它们,但通常你只是比较所有字段。 可能添加一个id字段也是一个好主意。 然后,如果模型具有相同的id ,则可以认为它们“相等”。 hashCode()你可以只返回Objects.hash(id)

现在,谈谈您关于ItemCallback的问题。 正式地,这是来自文档的解释:

DiffUtil.Callback 有两个角色 - 列表索引和项目差异。 ItemCallback 只处理其中的第二个,它允许将索引到数组或列表中的代码与表示层和内容特定的差异代码分开。

实际上, ItemCallback只需实现较少的方法并与AsyncListDiffer一起使用。 这只是因为缺少的方法已经在 AsyncListDiffer 的底层实现了。

您必须覆盖 model 类的等号和哈希码。

常规模型:

class RoutineModel {
    private ArrayList<RoutineDetailModel> routineDetailModels;
    private String            routine;

    public RoutineModel(ArrayList<RoutineDetailModel> items, String routine) {
        this.routine = routine;
        this.routineDetailModels = items;
    }

    public ArrayList<RoutineDetailModel> getDetailItemList() {
        return routineDetailModels;
    }

    public int getDetailItemSize() {
        return routineDetailModels.size();
    }

    public String getRoutine() {
        return routine;
    }

    public void setRoutine(String routine) {
        this.routine = routine;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RoutineModel that = (RoutineModel) o;
        return Objects.equals(routineDetailModels, that.routineDetailModels) &&
            Objects.equals(routine, that.routine);
    }

    @Override
    public int hashCode() {
        return Objects.hash(routineDetailModels, routine);
    }
}

RoutineDiffUtil:

public class RoutineDiffUtil extends DiffUtil.Callback {
    private final List<RoutineModel> oldRoutineList;
    private final List<RoutineModel> newRoutineList;

    public RoutineDiffUtil(ArrayList<RoutineModel> oldRoutineList, ArrayList<RoutineModel> newRoutineList) {
        this.oldRoutineList = oldRoutineList;
        this.newRoutineList = newRoutineList;
    }

    @Override
    public int getOldListSize() {
        return oldRoutineList.size();
    }

    @Override
    public int getNewListSize() {
        return newRoutineList.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldRoutineList.get(oldItemPosition).getRoutine().equals(newRoutineList.get(newItemPosition).getRoutine());
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        return oldRoutineList.get(oldItemPosition).equals(newRoutineList.get(newItemPosition));
    }
}

并且不要忘记覆盖您的RoutineDetailModel的等号和哈希码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM