简体   繁体   English

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

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

I am now making a DiffUtil class to update only changed items in the RecyclerView .我现在正在制作DiffUtil class 以仅更新RecyclerView中更改的项目。

I have seen several other sample code.我看过其他几个示例代码。

When comparing two objects, they compared unique values such as id defined in the Model(Data) class in areItemsTheSame() .在比较两个对象时,他们比较了唯一值,例如在areItemsTheSame()中的Model(Data) class 中定义的 id。

However, I think it is difficult to assign an id or unique value to the List, or the code is messy.但是,我认为很难为 List 分配一个idunique value ,或者代码很乱。

Do I have to define and compare id like this?我必须像这样定义和比较id吗?

Do I really need to define a unique Id variable in the Model class that separates each object?我真的需要在Model class中定义一个唯一的 Id 变量来分隔每个 object 吗? Or shouldn't I use simply the equals() ?或者我不应该简单地使用equals()吗?

Using this Is it not just comparing the address of the object, but also the contents of the object?用这个不就是比较object的地址,还要比较object的内容吗?

As an additional question作为一个附加问题

What is the difference between DiffUtil.CallBack and DiffUtil.ItemCallBack ? DiffUtil.CallBackDiffUtil.ItemCallBack什么区别?

This is my code.这是我的代码。

RoutineModel.java例程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;
    }
}

RoutineDiffUtil.java例程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);
    }
}

You got wrong the meaning of areItemsTheSame() and areContentsTheSame() callbacks.你弄错了areItemsTheSame()areContentsTheSame()回调的含义。 As you see, there are oldItemPosition and newItemPosition arguments in them.如您所见,其中有oldItemPositionnewItemPosition arguments。 You should use them to compare specific items – not lists themselves.您应该使用它们来比较特定项目——而不是列出它们本身。

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 . 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 . This is how DiffUtil knows if it has to make reordering animations.这就是 DiffUtil 知道它是否必须制作重新排序动画的方式。

areContentsTheSame() will be called for two items if and only if you return true for them in the previous callback.当且仅当您在上一个回调中为它们返回true时,才会为两个项目调用areContentsTheSame() Here you have to check whether visual representation of "old" and "new" models is the same.在这里,您必须检查“旧”和“新”模型的视觉表示是否相同。 This is how DiffUtil knows if it has to make "item changing" animations.这就是 DiffUtil 知道它是否必须制作“项目更改”动画的方式。

To compare two models you have to override equals() and hashCode() .要比较两个模型,您必须覆盖equals()hashCode() There you specify conditions under which you consider two models the same.在那里您指定您认为两个模型相同的条件。 For example, if they have same routine .例如,如果他们有相同的routine I don't the know context of your task so I can't tell you exactly how to implement them, but usually you just compare all fields.我不知道你的任务的上下文,所以我不能确切地告诉你如何实现它们,但通常你只是比较所有字段。 Probably adding an id field is a good idea too.可能添加一个id字段也是一个好主意。 Then you can consider models "equal" if they have same id .然后,如果模型具有相同的id ,则可以认为它们“相等”。 And in hashCode() you can just return Objects.hash(id) .hashCode()你可以只返回Objects.hash(id)

Now, speaking about your question about ItemCallback .现在,谈谈您关于ItemCallback的问题。 Formally, here is the explanation from docs:正式地,这是来自文档的解释:

DiffUtil.Callback serves two roles - list indexing, and item diffing. DiffUtil.Callback 有两个角色 - 列表索引和项目差异。 ItemCallback handles just the second of these, which allows separation of code that indexes into an array or List from the presentation-layer and content specific diffing code. ItemCallback 只处理其中的第二个,它允许将索引到数组或列表中的代码与表示层和内容特定的差异代码分开。

Practically, ItemCallback just has less methods to implement and is used together with AsyncListDiffer .实际上, ItemCallback只需实现较少的方法并与AsyncListDiffer一起使用。 It's just because missing methods are already implemented under the hood in AsyncListDiffer.这只是因为缺少的方法已经在 AsyncListDiffer 的底层实现了。

You have to override the equals and hashcodes of your model classes.您必须覆盖 model 类的等号和哈希码。

RoutineModel:常规模型:

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: 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));
    }
}

And don't forget to override the equals and hashcode of your RoutineDetailModel .并且不要忘记覆盖您的RoutineDetailModel的等号和哈希码。

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

相关问题 我可以让我的应用程序使用我自己的 class 实现,而不是来自外部 jar 的 class - Can I have my application use my own implementation of a class instead of the class from a external jar 如何在下面的上下文中干燥我的代码(android) - How can I DRY my code in the context below(android) 如何在我的Java代码上使用回调方法? - How can i use callback method on my java code? 我可以在我的java代码中使用两个ssh java lib吗? - can I use two ssh java lib in my java code? 为什么在Java的代码中不能使用“返回”? - Why I can't use “return” in my code at Java? 我的代码有什么问题,我不能使用KeyPressed方法? - What wrong with my code , I can't use KeyPressed method? 我无法在我的代码中使用 findOne() 方法 - I can't use findOne() method in my code 我可以在同一个项目中使用本机语言支持和 Java 代码实现吗 - Can I use Native language support and Java code implementation in same project 如何在 android 2.2.2 (Froyo) 中使用 BitmapRegionDecoder 代码? - How can I use BitmapRegionDecoder code in android 2.2.2 (Froyo)? 如何在android studio中隐藏我的源代码? - how can i hide my source code in android studio?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM