添加,删除和移动项目后,如何正确更新RecyclerViewAdapter?

时间:2016-03-18 13:28:54

标签: android android-recyclerview

我正在寻找一个图书馆,要点,摘要或最佳做法来帮助我更新我的RecyclerView.Adapter,当我收到一些项目列表,其中一些项目是新添加的,一些已移动,一些已保留,一些已被删除。我不想使用notifyDatasetChanged,因为我希望可以在视觉上移动移动的项目。

我找不到任何东西。所以我最终自己动手做了。

  

两件事:

1。是否有图书馆,要点,摘要或最佳做法?

2. 你们可以就我的解决方案提供反馈意见吗?太可怕了吗?我能做些什么不同?你会用它吗?

我尝试尽可能地使用我的解决方案。你可以用两种方式;让它将项目放入适配器并更新它,或者它可以返回每个项目的状态列表,以便您自己处理更新。

public class RecyclerViewAdapterItemsUpdatedHelper<T, A extends RecyclerView.Adapter>{

List<T> currentItems;
List<T> newItems;

public RecyclerViewAdapterItemsUpdatedHelper(
                                             List<T> currentItems,
                                             List<T> newItems) {
    this.currentItems = currentItems;
    this.newItems = newItems;
}

public enum State {
    ADDED, MOVED, REMOVED, KEPT
}

public boolean helpMeHandleIt(A adapter) {
    log(currentItems, newItems);

    boolean moved = false;
    boolean added = false;
    boolean removed = false;

    for (int i = currentItems.size() -1; i > -1; i--) {
        if (!newItems.contains(currentItems.get(i))) {
            currentItems.remove(i);
            adapter.notifyItemRemoved(i);
            removed = true;
        }
    }

    for (int i = 0; i < newItems.size(); i++) {
        State state;
        try {
            if (!newItems.get(i).equals(currentItems.get(i))) {
                state = currentItems.contains(newItems.get(i)) ? State.MOVED : State.ADDED;

                if (state.equals(State.ADDED)) {
                    currentItems.add(i, newItems.get(i));
                    adapter.notifyItemInserted(i);
                    added = true;
                } else if (state.equals(State.MOVED)) {
                    int from = currentItems.indexOf(newItems.get(i));
                    currentItems.remove(from);
                    currentItems.add(i, newItems.get(i));
                    adapter.notifyItemMoved(from, i);
                    moved = true;
                }
            }
        } catch (IndexOutOfBoundsException e) {
            currentItems.add(i, newItems.get(i));
            adapter.notifyItemInserted(i);
            added = true;
        }
    }

    return moved && !added && !removed;
}

public List<StatusItem> justGiveMeStatus() {
    log(currentItems, newItems);

    List<StatusItem> statusItems = new ArrayList<>();

    for (int i = currentItems.size() -1; i > -1; i--) {
        if (!newItems.contains(currentItems.get(i))) {
            statusItems.add(new StatusItem(currentItems.get(i), State.REMOVED, i, -1));
        }
    }

    for (int i = 0; i < newItems.size(); i++) {
        State state;
        try {
            if (!newItems.get(i).equals(currentItems.get(i))) {
                state = currentItems.contains(newItems.get(i)) ? State.MOVED : State.ADDED;

                if (state.equals(State.ADDED)) {
                    statusItems.add(new StatusItem(newItems.get(i), State.ADDED, -1, i));
                } else if (state.equals(State.MOVED)) {
                    int from = currentItems.indexOf(newItems.get(i));
                    statusItems.add(new StatusItem(newItems.get(i), State.MOVED, from, i));
                }
            } else {
                statusItems.add(new StatusItem(newItems.get(i), State.KEPT, i, i));
            }
        } catch (IndexOutOfBoundsException e) {
            statusItems.add(new StatusItem(newItems.get(i), State.ADDED, -1, i));
        }
    }
    return statusItems;
}

private void log(List<T> currentItems, List<T> newItems) {
    for (T obj :
            currentItems) {
        Log.i("current item", obj.toString());
    }

    for (T obj :
            newItems) {
        Log.i("new item", obj.toString());
    }
}

public class StatusItem {
    private T item;
    private State status;
    private int from = -1;
    private int to = -1;

    public StatusItem(T item, State status) {
        this.item = item;
        this.status = status;
    }

    public StatusItem(T item, State status, int from, int to) {
        this.item = item;
        this.status = status;
        this.from = from;
        this.to = to;
    }

    public T getItem() {
        return item;
    }

    public State getStatus() {
        return status;
    }

    public int getFrom() {
        return from;
    }

    public int getTo() {
        return to;
    }

    @Override
    public String toString() {
        return item.toString() + " | " + status +
                 " | " + from + " -> " + to;
    }
}

0 个答案:

没有答案