如何在android中使用MVP Structure刷新recyclelerview?

BK1*_*K19 5 mvp android android-recyclerview

我想在android中的MVP结构的简单示例来刷新recyclerview项目而不是recyclelerview的整个列表.

它只刷新android的recyclerview中的项目.

Jah*_*old 4

这是我思考了很多的问题。有两种可能的方法:

  • 将新的数据列表传递给适配器,它会计算出更改的内容并更新正确的项目。
  • 记录模型中的当前项目,然后在计算新列表时将ListChangeItems 发送到适配器。

我将在下面更详细地概述两者。在这两种情况下,您都需要计算当前显示的数据与新数据之间的差异。我有一个辅助类ListDiffHelper<T>可以进行此比较:

public class ListDiffHelper<T> {

    private List<T> oldList;
    private List<T> newList;

    private List<Integer> inserted = new ArrayList<>();
    private List<Integer> removed = new ArrayList<>();

    public List<Integer> getInserted() {return inserted;}
    public List<Integer> getRemoved() {return removed;}

    public ListDiffHelper(List<T> oldList, List<T> newList) {

        this.oldList = oldList;
        this.newList = newList;

        checkForNull();

        findInserted();
        findRemoved();
    }

    private void checkForNull() {

        if (oldList == null) oldList = Collections.emptyList();
        if (newList == null) newList = Collections.emptyList();
    }

    private void findInserted() {

        Set<T> newSet = new HashSet<>(newList);
        newSet.removeAll(new HashSet<>(oldList));

        for (T item : newSet) {
            inserted.add(newList.indexOf(item));
        }

        Collections.sort(inserted, new Comparator<Integer>() {
            @Override
            public int compare(Integer lhs, Integer rhs) {
                return lhs - rhs;
            }
        });
    }

    private void findRemoved() {

        Set<T> oldSet = new HashSet<>(oldList);
        oldSet.removeAll(new HashSet<>(newList));

        for (T item : oldSet) {
            removed.add(oldList.indexOf(item));
        }

        Collections.sort(inserted, new Comparator<Integer>() {
            @Override
            public int compare(Integer lhs, Integer rhs) {
                return rhs - lhs;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使其正常工作,您需要确保equals()Data 类的方法以合适的方式比较事物。

适配器引线

在这种情况下,您的 Presenter 调用getData()模型(或者如果您使用 Rx 则订阅它)并接收List<Data>. 然后,它通过一个方法将此列表传递给视图,setData(data)视图又将该列表提供给适配器。适配器中的方法类似于:

private void setData(List<Data> data) {

    if (this.data == null || this.data.isEmpty() || data.isEmpty()) {
        this.data = data;
        adapter.notifyDataSetChanged();
        return;
    }

    ListDiffHelper<Data> diff = new ListDiffHelper<>(this.data, data);
    this.data = data;

    for (Integer index : diff.getRemoved()) {
       notifyItemRemoved(index);
    }
    for (Integer index : diff.getInserted()) {
       notifyItemInserted(index);
    }
}
Run Code Online (Sandbox Code Playgroud)

在添加新项目之前先删除项目非常重要,否则将无法正确维护订单。

模特领衔

另一种方法是让适配器更加愚蠢,并计算模型层中发生的变化。然后,您需要一个包装类来将各个更改发送到您的视图/适配器。就像是:

public class ListChangeItem {

    private static final int INSERTED = 0;
    private static final int REMOVED = 1;

    private int type;
    private int position;
    private Data data;

    public ListChangeItem(int type, int position, Data data) {
        this.type = type;
        this.position = position;
        this.data = data;
    }

    public int getType() {return type;}
    public int getPosition() {return position;}
    public Data getData() {return data;}
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过视图界面将这些列表传递给您的适配器。同样,在插入之前执行删除操作以确保数据的顺序正确也很重要。