[英](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 分配一个id
或unique 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.CallBack
和DiffUtil.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.如您所见,其中有oldItemPosition
和newItemPosition
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.