如何使用DiffUtil获取插入项目的位置?

时间:2019-02-17 06:11:11

标签: android android-recyclerview recycler-adapter

我已经在一个相当简单的问题上停留了一段时间。出于某种原因,我无法在此找到StackOverflow的答案,所以我想直接寻求帮助。

问题很简单,我有一个按日期排序的Transaction对象列表。我要向列表中添加一个新的交易,然后重新使用它。由于我不知道新交易的添加位置,因此我尝试使用DiffUtil为我自己找出并适当更新RecyclerView的内容。

但是,我得到的结果确实很奇怪。由于某些原因,整个列表都在更新,订单被完全弄乱了。但是,基础数据是正确的。

在更新列表之前: enter image description here

更新列表后: enter image description here 这是我在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;
}
}

任何帮助将不胜感激。请让我知道是否需要更多信息来澄清问题。

1 个答案:

答案 0 :(得分:0)

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;
}