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

Android 如何使用MVP从RecyclerView插入/删除项目,android,architecture,android-recyclerview,mvp,Android,Architecture,Android Recyclerview,Mvp,在MVP中使用recycler视图时,你们在哪里保留对列表的引用?我有一个ChatManager,可以与不同的演讲者交谈。我保留了两份邮件列表,一份在ChatManager中,另一份在Presenter中。适配器、视图和演示者共享同一列表。 我之所以要引用演示者中的消息列表,是因为我有一些要从演示者中删除和滚动的业务逻辑 因此,现在当我必须删除一条消息时,演示者决定删除哪个项目并将其从列表中删除。现在需要让视图知道消息已被删除。那么在这种情况下,它应该说view.remove(message)还

在MVP中使用recycler视图时,你们在哪里保留对列表的引用?我有一个
ChatManager
,可以与不同的演讲者交谈。我保留了两份邮件列表,一份在
ChatManager
中,另一份在
Presenter
中。适配器、视图和演示者共享同一列表。 我之所以要引用演示者中的消息列表,是因为我有一些要从演示者中删除和滚动的业务逻辑

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

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


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

最佳做法是从视图实现中更新适配器列表,但此任务的功能应在视图接口上,并在视图实现中实现(例如片段或活动)

首先向适配器添加一个方法,如下所示

public void updateItemsList(ItemsList itemsList)
{
   //update the list of your items assume your items list is named "mItemsList"
   this.mItemsList = itemsList;
   notifyDataSetChanged();
}
public void updateAdapterList(ItemsList itemsList);
然后在视图界面中添加一个方法来更新适配器列表,如下所示

public void updateItemsList(ItemsList itemsList)
{
   //update the list of your items assume your items list is named "mItemsList"
   this.mItemsList = itemsList;
   notifyDataSetChanged();
}
public void updateAdapterList(ItemsList itemsList);
然后在视图实现(片段或活动)中添加以下内容:

@Override
public void updateAdapterList(ItemsList itemsList);
{
   //update the adapter list -- assume your adapter is named "mAdapter"
   mAdapter.updateItemsList(itemsList);
}

现在,只要有view interface类型的对象,就可以访问此方法(UpdateDapterList())。

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

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

我采用的解决方案是将整个更新列表从
演示者
传递到
视图
,最终将其传递到
适配器
适配器
然后使用
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);
    }
}
ChatPresenter{
界面视图{
...
作废更新消息(列出消息);
}
活动实现ChatPresenter.View{
...
@凌驾
作废更新消息(列出消息){
更新(消息);
}
}
查塔普特{
...
公共更新(列出消息){
DiffUtil.diffesult diffesult=DiffUtil.calculateDiff(新ChatMessageDiffCallback(this.messages,updateMessages));
this.messages=更新的消息;
diffResult.dispatchUpdatesTo(本);
}
}

我这样做了:我将数据列表存储在presenter中,无需复制以查看。当presenter(从模型)中发生更改时,我可以调用
view.changeData()
,您的活动/片段可以通过
presenter.getData()
访问数据。对视图执行的操作对presenter具有相关方法(添加新邮件,加载更多…)@akshayt23首次设置数据列表视图。在任何受影响的更改之后,例如(添加、编辑、删除)选项流,例如notifyItemInserted(int lastPostion)Edit NotifyItemChanged(int position)get position by unique id从邮件中删除也相同