Я застрял на довольно простой проблеме в течение некоторого времени. И по какой-то причине я не могу найти ответы на StackOverflow по этому поводу, поэтому я решил обратиться за помощью напрямую.
Проблема проста, у меня есть список объектов Transaction, отсортированных по дате. Я добавляю новую транзакцию в список, а затем прибегаю к ней. Поскольку я не знаю позицию, в которой была добавлена новая транзакция, я пытаюсь использовать DiffUtil, чтобы выяснить это для меня и соответствующим образом обновить содержимое RecyclerView.
Однако результат, который я получаю, действительно странный. По какой-то причине весь список обновляется, и порядок становится полностью перепутанным. Однако исходные данные верны.
После обновления списка:
Вот код, который у меня есть в моем Adapter для добавления нового элемента транзакции.
void addItem(Transaction transaction) {
ArrayList<Transaction> oldList = new ArrayList<>(transactions);
transactions.add(transaction);
Collections.sort(transactions);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallback(oldList, transactions), false);
diffResult.dispatchUpdatesTo(this);
}
И, наконец, вот моя DiffUtilCallback реализация
class DiffCallback extends DiffUtil.Callback {
private List<Transaction> oldList;
private List<Transaction> newList;
public DiffCallback(List<Transaction> oldList, List<Transaction> newList) {
this.oldList = oldList;
this.newList = newList;
}
@Override
public int getOldListSize() {
return oldList.size();
}
@Override
public int getNewListSize() {
return newList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
Transaction oldItem = oldList.get(oldItemPosition);
Transaction newItem = newList.get(oldItemPosition);
return oldItem.equals(newItem);
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
Transaction oldItem = oldList.get(oldItemPosition);
Transaction newItem = newList.get(oldItemPosition);
return oldItem.equals(newItem);
}
}
Вот класс Transaction
public class Transaction implements Comparable<Transaction> {
public String category;
public String description;
public Date date;
public Double amount;
public Transaction(String description, Date date, Double amount) {
this.category = "";
this.description = description;
this.date = date;
this.amount = amount;
}
public Transaction(String category, String description, Date date, Double amount) {
this.category = category;
this.description = description;
this.date = date;
this.amount = amount;
}
@Override
public int compareTo(@NonNull Transaction transaction) {
if (this.category.compareTo(transaction.category) == 0) {
return this.date.compareTo(transaction.date);
}
return this.category.compareTo(transaction.category);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Transaction)) {
return false;
}
Transaction other = (Transaction)obj;
return this.category.equals(other.category)
&& this.description.equals(other.description)
&& this.date.equals(other.date)
&& this.amount.equals(other.amount);
}
@Override
public String toString() {
return description;
}
}
Любая помощь будет оценена. Пожалуйста, дайте мне знать, если для выяснения проблемы требуется дополнительная информация.
@KishoreJethava опубликовал
Сначала вы сортируете по Transaction.category, а затем по Transaction.date. Из скриншота видно, что ваши транзакции отсортированы по date, но в двух разных наборах. Я подозреваю, что ваш код работает правильно.
Если вы просто хотите отсортировать по date, удалите части о category в compareTo.
@HamedMomeni Спасибо за комментарий. category был добавлен, потому что это часть более крупного приложения. Но на предоставленных скриншотах всем транзакциям была присвоена одна и та же категория, так что, вероятно, проблема не в этом.
В areContentsTheSame вы должны сравнивать атрибуты Transaction, но вы сравниваете Transaction сам объект.
обновлено areContentsTheSame
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
Transaction oldItem = oldList.get(oldItemPosition);
Transaction newItem = newList.get(oldItemPosition);
return oldItem.category == newItem.category && oldItem.description== newItem.description && oldItem.date== newItem.date && oldItem.amount == newItem.amount;
}
Да, для этого я реализовал метод equals внутри Transaction. Пожалуйста, посмотрите код Transaction в моем вопросе.
Comparable<Transaction> не требуется для реализации в TransactionЯ хочу отсортировать транзакции в порядке их возникновения (по дате) и категории. Вот почему я реализую Comparable. Вы думаете, что это может вызвать проблемы?
О, я забыл это. У вас возникает такая же проблема?
пост
Transactionкласс