(android) 我可以在我的 DiffUtill 实现中使用此代码吗?
(android) Can I use this code in my DiffUtill implementation?
我现在正在制作 DiffUtil
class 以仅更新 RecyclerView
中更改的项目。
我看过其他几个示例代码。
比较两个对象时,比较的是areItemsTheSame()
中class中定义的id等唯一值。
不过我觉得给List分配一个id
或者unique value
比较难,或者代码比较乱。
我必须这样定义和比较id
吗?
我真的需要在 Model class
中定义一个唯一的 Id 变量来分隔每个对象吗?
或者我不应该只使用 equals()
?
用这个是不是不仅要比较对象的地址,还要比较对象的内容?
作为附加问题
DiffUtil.CallBack
和DiffUtil.ItemCallBack
有什么区别?
这是我的代码。
RoutineModel.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
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
参数。您应该使用它们来比较特定项目——而不是列表本身。
在areItemsTheSame()
中你必须检查旧列表中“旧”位置的模型是否等于中“新”位置的模型新列表。这就是 DiffUtil 知道是否必须制作重新排序动画的方式。
areContentsTheSame()
当且仅当您在上一个回调中为它们 return true
时,才会为两个项目调用。在这里您必须检查“旧”和“新”模型的视觉表示是否相同。这就是 DiffUtil 知道它是否必须制作“项目更改”动画的方式。
要比较两个模型,您必须覆盖 equals()
和 hashCode()
。您可以在其中指定将两个模型视为相同的条件。例如,如果他们有相同的 routine
。我不知道你任务的背景,所以我不能告诉你具体如何实现它们,但通常你只是比较所有领域。可能添加一个 id
字段也是一个好主意。然后,如果模型具有相同的 id
,则您可以认为模型“相等”。在 hashCode()
中你可以 return Objects.hash(id)
.
现在,谈谈你关于 ItemCallback
的问题。正式地,这是来自文档的解释:
DiffUtil.Callback serves two roles - list indexing, and item diffing. 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
只是实现方法较少,与AsyncListDiffer一起使用。这只是因为缺少的方法已经在 AsyncListDiffer 中实现了。
您必须覆盖模型的等号和哈希码 类。
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:
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.
的等号和哈希码
我现在正在制作 DiffUtil
class 以仅更新 RecyclerView
中更改的项目。
我看过其他几个示例代码。
比较两个对象时,比较的是areItemsTheSame()
中class中定义的id等唯一值。
不过我觉得给List分配一个id
或者unique value
比较难,或者代码比较乱。
我必须这样定义和比较id
吗?
我真的需要在 Model class
中定义一个唯一的 Id 变量来分隔每个对象吗?
或者我不应该只使用 equals()
?
用这个是不是不仅要比较对象的地址,还要比较对象的内容?
作为附加问题
DiffUtil.CallBack
和DiffUtil.ItemCallBack
有什么区别?
这是我的代码。
RoutineModel.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
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
参数。您应该使用它们来比较特定项目——而不是列表本身。
在areItemsTheSame()
中你必须检查旧列表中“旧”位置的模型是否等于中“新”位置的模型新列表。这就是 DiffUtil 知道是否必须制作重新排序动画的方式。
areContentsTheSame()
当且仅当您在上一个回调中为它们 return true
时,才会为两个项目调用。在这里您必须检查“旧”和“新”模型的视觉表示是否相同。这就是 DiffUtil 知道它是否必须制作“项目更改”动画的方式。
要比较两个模型,您必须覆盖 equals()
和 hashCode()
。您可以在其中指定将两个模型视为相同的条件。例如,如果他们有相同的 routine
。我不知道你任务的背景,所以我不能告诉你具体如何实现它们,但通常你只是比较所有领域。可能添加一个 id
字段也是一个好主意。然后,如果模型具有相同的 id
,则您可以认为模型“相等”。在 hashCode()
中你可以 return Objects.hash(id)
.
现在,谈谈你关于 ItemCallback
的问题。正式地,这是来自文档的解释:
DiffUtil.Callback serves two roles - list indexing, and item diffing. 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
只是实现方法较少,与AsyncListDiffer一起使用。这只是因为缺少的方法已经在 AsyncListDiffer 中实现了。
您必须覆盖模型的等号和哈希码 类。
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:
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.
的等号和哈希码