![](/img/trans.png)
[英]Can I have my application use my own implementation of a class instead of the class from a external jar
[英](android) Can I use this code in my DiffUtill implementation?
我现在正在制作DiffUtil
class 以仅更新RecyclerView
中更改的项目。
我看过其他几个示例代码。
在比较两个对象时,他们比较了唯一值,例如在areItemsTheSame()
中的Model(Data)
class 中定义的 id。
但是,我认为很难为 List 分配一个id
或unique value
,或者代码很乱。
我必须像这样定义和比较id
吗?
我真的需要在Model class
中定义一个唯一的 Id 变量来分隔每个 object 吗? 或者我不应该简单地使用equals()
吗?
用这个不就是比较object的地址,还要比较object的内容吗?
作为一个附加问题
DiffUtil.CallBack
和DiffUtil.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()
回调的含义。 如您所见,其中有oldItemPosition
和newItemPosition
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.