I'm implementing a recycler view using room database library. I would like to list my items and that they could be edited by clicking. After re-submit the item, go back again to the list and show up the items + changes.
I'm currently using DiffUtil callback to compare the old and the new lists. I think the problem is here. My Dto item has 4 fields.
So when the user edits an item, the list should update the UI row (title, image or/and arraylist)
This is my Adapter.
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;
}
The problem: when an item is updated, changing the title for example, the list gets updated, but the eddited item disappears. If i end the activity and start it again, the item updated is there. So the problem must be the diff callback, but I'm not really able to make it work. Sorry for my English, this is not my main language, thanks all!
Most probably you are not properly using the DiffUtil
functionality. You first need to calculate diff and then dispatch updates to adapter after which it will refresh your adapter with the new data. Use DiffUtil.Callback()
and not 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
You can read more about Diff Util here and here
Let me know if you still have doubts. Thanks.