如何使用 MVP 从 RecyclerView 插入/删除项目 [英] How to insert/remove items from RecyclerView using MVP

查看:23
本文介绍了如何使用 MVP 从 RecyclerView 插入/删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 MVP 中使用回收器视图时,你们在哪里保存对列表的引用?我有一个 ChatManager 可以与不同的演示者交谈.我保留了两个消息列表副本,一个在 ChatManager 中,另一个在 Presenter 中.适配器、视图和演示者共享同一个列表.我在 Presenter 中引用消息列表的原因是因为我有一些删除和滚动的业务逻辑,我想从演示者那里处理.

While using recycler view in MVP, where do you guys keep a reference to the list? I have a ChatManager which can talk to different presenters. I keep two copies of the list of messages , one in the ChatManager and the other in the Presenter. The adapter, view, and the presenter share the same list. The reason I have a reference to the list of messages in the Presenter is because I have some business logic for removal and scrolling which I want to handle from the presenter.

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

So now when I have to remove a message, the presenter decides what item to remove and removes it from the list. Now it needs to let the view know that a message has been removed. So in that case, should it say view.remove(message) or view.remove(index)? The view should not try and remove the message again since the presenter has already done that.

其他操作如滚动或添加也是如此.如果接收到新消息,演示者将 newMessages 添加到 allMessages,然后必须更新视图.理想情况下,演示者应该调用 view.onMessagesReceived(List messages) 而不是 view.onMessageReceived(int newMessagesCount, int indexAddedAt).第二种方法真的很奇怪,一点也不冗长.但是由于列表是共享的,视图只需要调用notifyItemInserted,因此只需要知道计数和索引.

Same thing for other operations like scrolling or adding. If new messages are received, the presenter adds the newMessages to allMessages and then has to update the view. Ideally, the presenter should be calling view.onMessagesReceived(List<Message> messages) instead of view.onMessageReceived(int newMessagesCount, int indexAddedAt). The second method is really weird and not verbose at all. But since the list is being shared, the view only needs to call notifyItemInserted and hence only needs to know about the count and the index.

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

What is the best way to handle this?

推荐答案

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

So as Amir suggested, one way to go about it is expose a method from the adapter to update the data, and call notifyDataSetChanged. I really didn't want to use this method as it unnecessarily refreshes the entire data set when I only wanted to add/update messages in the adapter.

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

Another way was to expose a method addNewMessages(int count, int index) in the view, so that the adapter knows which indices to notify insert/update for, which I again didn't want to use because then the API seems weird as addNewMessages should actually be passed the list of new messages instead of the index and count.

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

The solution I went with was to actually pass the entire updated list from the Presenter to the View, which eventually passes it to the Adapter. The Adapter then uses DiffUtil to figure out the diff between the old list and the new list and calls only the notifyItemInserted/notifyItemChanged methods instead of notifyDataSetChanged every time.

这很有帮助,因为现在 API 如下所示:

This helps because now the API looks like this:

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

这篇关于如何使用 MVP 从 RecyclerView 插入/删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆