android – 如何使用MVP从RecyclerView插入/删除项目

在MVP中使用Recycler视图时,你们在哪里保留对列表的引用?我有一个ChatManager,可以与不同的演示者交谈.我保留了两份消息列表,一份在ChatManager中,另一份在Presenter中.适配器,视图和演示者共享相同的列表.

我在Presenter中引用消息列表的原因是因为我有一些用于删除和滚动的业务逻辑,我想从演示者处理它.

所以现在当我必须删除一条消息时,演示者决定删除哪个项目并将其从列表中删除.现在需要让视图知道消息已被删除.那么在这种情况下,它应该说view.remove(message)还是view.remove(index)?视图不应该尝试再次删除该消息,因为演示者已经这样做了.

与滚动或添加等其他操作相同.如果收到新消息,则演示者将newMessages添加到allMessages,然后必须更新视图.理想情况下,演示者应该调用view.onMessagesReceived(List< Message> messages)而不是view.onMessageReceived(int newMessagesCount,int indexAddedAt).第二种方法非常奇怪,而且根本没有冗长.但是由于列表正在共享,因此视图只需要调用notifyItemInserted,因此只需要知道计数和索引.

处理这个问题的最佳方法是什么?

最佳答案 正如Amir建议的那样,一种方法是从适配器公开一个方法来更新数据,并调用notifyDataSetChanged.我真的不想使用这种方法,因为当我只想在适配器中添加/更新消息时,它会不必要地刷新整个数据集.

另一种方法是在视图中公开方法addNewMessages(int count,int index),以便适配器知道哪些索引通知插入/更新,我再次不想使用,因为那时API似乎很奇怪,因为addNewMessages实际上应该传递新消息列表而不是索引和计数.

我使用的解决方案是将整个更新列表从Presenter实际传递给View,最终将其传递给Adapter.然后,适配器使用DiffUtil来计算旧列表和新列表之间的差异,并且每次只调用notifyItemInserted / notifyItemChanged方法而不是notifyDataSetChanged.

这有帮助,因为现在API看起来像这样:

ChatPresenter {
    interface View {
    ...
    void updateMessages(List<Message> messages);
}

Activity implements ChatPresenter.View {
    ...
    @Override
    void updateMessages(List<Message> messages) {
        chatsAdapter.update(messages);
    }
}

ChatsAdapter {
    ...
    public update(List<Message> messages) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new ChatMessageDiffCallback(this.messages, updatedMessages));

        this.messages = updatedMessages;
        diffResult.dispatchUpdatesTo(this);
    }
}
点赞