如何使用差异项目回调更新回收站视图中的项目?
How to update item in a recycler view using diff item callback?
我正在使用房间数据库实现回收器视图。我想列出我的项目,并且可以通过单击对其进行编辑。 re-submit 项目后,再次返回列表并显示项目 + 更改。
我目前正在使用 DiffUtil 回调来比较新旧列表。我觉得问题就出在这里。我的 Dto 项有 4 个字段。
- id标题图片数组列表
所以当用户编辑一个项目时,列表应该更新 UI 行(标题,图像 or/and arraylist)
这是我的适配器。
private OnItemClickListener listener;
public ExercicioAdapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<Exercicio> DIFF_CALLBACK = new DiffUtil.ItemCallback<Exercicio>() {
@Override
public boolean areItemsTheSame(@NonNull Exercicio oldExercicio, @NonNull Exercicio newExercicio) {
return oldExercicio.getId() == newExercicio.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Exercicio oldExercicio, @NonNull Exercicio newExercicio) {
return oldExercicio.getTitulo().equals(newExercicio.getTitulo()) &&
Float.compare(oldExercicio.getMaxPeso(), newExercicio.getMaxPeso()) == 0;
}
};
@NonNull
@Override
public MyHolderView onCreateViewHolder(@NonNull ViewGroup parent, int i) {
View view;
LayoutInflater mInflater = LayoutInflater.from(parent.getContext());
view = mInflater.inflate(R.layout.exercicios_item, parent, false);
return new MyHolderView(view);
}
@Override
public void onBindViewHolder(@NonNull MyHolderView exercicioHolder, final int i) {
Exercicio exercicio = getItem(i);
// Mostrar a informacion do obxeto.
ArrayList<Repeticion> repeticions = exercicio.getRepeticions();
float peso_max = 0f;
if (repeticions != null && repeticions.size() > 0) {
for (Repeticion rep : repeticions) {
if (rep.getPeso() > peso_max) {
peso_max = rep.getPeso();
}
}
}
exercicioHolder.nome.setText(exercicio.getTitulo());
String peso_str = exercicioHolder.itemView.getContext().getString(R.string.peso_max);
exercicioHolder.peso.setText(peso_str + " " + Float.toString(peso_max));
if (exercicio.getImaxe() != null && exercicio.getImaxe().length != 0) {
exercicioHolder.imx_exercicio.setImageBitmap(convertByteArrayToBitmap(exercicio.getImaxe()));
}
}
public Exercicio getExercicioAt(int position) {
return getItem(position);
}
public class MyHolderView extends RecyclerView.ViewHolder {
TextView nome;
TextView peso;
ImageView imx_exercicio;
CardView exercicio_cardview;
MyHolderView(@NonNull View itemView) {
super(itemView);
exercicio_cardview = itemView.findViewById(R.id.exercicio_cardview);
nome = itemView.findViewById(R.id.nome);
peso = itemView.findViewById(R.id.peso);
imx_exercicio = itemView.findViewById(R.id.imx_exercicio);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(getItem(position));
}
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Exercicio exercicio);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
问题:当更新项目时,例如更改标题,列表得到更新,但编辑的项目消失了。如果我结束 activity 并再次启动它,更新的项目就在那里。所以问题一定是 diff 回调,但我真的无法让它工作。对不起我的英语,这不是我的主要语言,谢谢大家!
很可能您没有正确使用 DiffUtil
功能。您首先需要计算差异,然后将更新分派给适配器,之后它将使用新数据刷新您的适配器。使用 DiffUtil.Callback()
和 而不是 DiffUtil.ItemCallback()
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
// old list size, which is same as new in your case
}
@Override
public int getNewListSize() {
// new list size, which is same as old in your case
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition)
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
}
)
result.dispatchUpdatesTo(this); // this parameter is your Recycler View's adapter
您可以阅读更多关于 Diff Util here and here
如果您仍有疑问,请告诉我。谢谢。
我正在使用房间数据库实现回收器视图。我想列出我的项目,并且可以通过单击对其进行编辑。 re-submit 项目后,再次返回列表并显示项目 + 更改。
我目前正在使用 DiffUtil 回调来比较新旧列表。我觉得问题就出在这里。我的 Dto 项有 4 个字段。
- id标题图片数组列表
所以当用户编辑一个项目时,列表应该更新 UI 行(标题,图像 or/and arraylist)
这是我的适配器。
private OnItemClickListener listener;
public ExercicioAdapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<Exercicio> DIFF_CALLBACK = new DiffUtil.ItemCallback<Exercicio>() {
@Override
public boolean areItemsTheSame(@NonNull Exercicio oldExercicio, @NonNull Exercicio newExercicio) {
return oldExercicio.getId() == newExercicio.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Exercicio oldExercicio, @NonNull Exercicio newExercicio) {
return oldExercicio.getTitulo().equals(newExercicio.getTitulo()) &&
Float.compare(oldExercicio.getMaxPeso(), newExercicio.getMaxPeso()) == 0;
}
};
@NonNull
@Override
public MyHolderView onCreateViewHolder(@NonNull ViewGroup parent, int i) {
View view;
LayoutInflater mInflater = LayoutInflater.from(parent.getContext());
view = mInflater.inflate(R.layout.exercicios_item, parent, false);
return new MyHolderView(view);
}
@Override
public void onBindViewHolder(@NonNull MyHolderView exercicioHolder, final int i) {
Exercicio exercicio = getItem(i);
// Mostrar a informacion do obxeto.
ArrayList<Repeticion> repeticions = exercicio.getRepeticions();
float peso_max = 0f;
if (repeticions != null && repeticions.size() > 0) {
for (Repeticion rep : repeticions) {
if (rep.getPeso() > peso_max) {
peso_max = rep.getPeso();
}
}
}
exercicioHolder.nome.setText(exercicio.getTitulo());
String peso_str = exercicioHolder.itemView.getContext().getString(R.string.peso_max);
exercicioHolder.peso.setText(peso_str + " " + Float.toString(peso_max));
if (exercicio.getImaxe() != null && exercicio.getImaxe().length != 0) {
exercicioHolder.imx_exercicio.setImageBitmap(convertByteArrayToBitmap(exercicio.getImaxe()));
}
}
public Exercicio getExercicioAt(int position) {
return getItem(position);
}
public class MyHolderView extends RecyclerView.ViewHolder {
TextView nome;
TextView peso;
ImageView imx_exercicio;
CardView exercicio_cardview;
MyHolderView(@NonNull View itemView) {
super(itemView);
exercicio_cardview = itemView.findViewById(R.id.exercicio_cardview);
nome = itemView.findViewById(R.id.nome);
peso = itemView.findViewById(R.id.peso);
imx_exercicio = itemView.findViewById(R.id.imx_exercicio);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(getItem(position));
}
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Exercicio exercicio);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
问题:当更新项目时,例如更改标题,列表得到更新,但编辑的项目消失了。如果我结束 activity 并再次启动它,更新的项目就在那里。所以问题一定是 diff 回调,但我真的无法让它工作。对不起我的英语,这不是我的主要语言,谢谢大家!
很可能您没有正确使用 DiffUtil
功能。您首先需要计算差异,然后将更新分派给适配器,之后它将使用新数据刷新您的适配器。使用 DiffUtil.Callback()
和 而不是 DiffUtil.ItemCallback()
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
// old list size, which is same as new in your case
}
@Override
public int getNewListSize() {
// new list size, which is same as old in your case
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition)
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
}
)
result.dispatchUpdatesTo(this); // this parameter is your Recycler View's adapter
您可以阅读更多关于 Diff Util here and here
如果您仍有疑问,请告诉我。谢谢。