如何跟踪选定的回收者视图项目?

时间:2019-11-23 08:13:06

标签: android android-recyclerview recycler-adapter android-pagedlistview notifyitemchanged

我有一个带有RecyclerView.Adapter适配器的recyclerview。使用PagedList从房间数据库填充项目。

长按一个项目时,我已经在工具栏上实现了上下文操作模式叠加,就像whatsapp一样。

contextual menu example

在View Holder中写入以下OnLongClickEvent:

@Override
public boolean onLongClick(View v) {
    final int previousSelected = selectedPos;
    selectedPos = getAdapterPosition();
    if(previousSelected!=RecyclerView.NO_POSITION){
        notifyItemChanged(previousSelected);        // Now deselect previously selected item
    }
    notifyItemChanged(selectedPos);                 // Select new item
    longClickCallback.onLongClick(binding.getMessage(),selectedPos);
    return true;
}

和selectedPos在适配器中初始化如下:

public static int selectedPos = RecyclerView.NO_POSITION;

长按事件将longClickCallback方法中的已单击项详细信息和选定项的位置发送回分段。

长按事件还包括取消选择/选择机制。基本上是这样的情况:长按选择项目,然后打开动作模式。然后,用户长按列表中的另一项只是取消选择较旧的项,然后选择新按下的项。 (当前我的选择仅适用于单个项目,我的意思是一次只能选择一项)。我需要在按下“后退”按钮或在动作模式下按下“后退”动作,或者长按新项时取消选择该项目。

只要适配器项位置不变,选择/取消选择机制就可以正常工作。实际上,如果将项目添加到列表的末尾,它也可以正常工作。 (滚动到较旧的消息)。

但是,当收到新消息并将其添加到列表的最顶部时,我的selectedItem位置不再正确。随着新添加邮件的数量而变化。

我认为更好的方法是保留该项目的ID,因为这对于所有适配器项目都是唯一的。但是notifyItemChanged使用项目的位置而不是项目本身。此外,然后我必须搜索所有项以通过我应该编写的自定义方法来获取所选项,但是我正在使用的消息列表中没有具有项ID的getItem:

private final AsyncPagedListDiffer<MessageUIEntity> mDiffer
        = new AsyncPagedListDiffer(this, DIFF_CALLBACK);

public static final DiffUtil.ItemCallback<MessageUI> DIFF_CALLBACK =
        new DiffUtil.ItemCallback<MessageUI>() {
            @Override
            public boolean areItemsTheSame(
                    @NonNull MessageUI oldMessage, @NonNull MessageUI newMessage) {
                // User properties may have changed if reloaded from the DB, but ID is fixed
                return oldMessage.getId() == newMessage.getId();
            }

            @Override
            public boolean areContentsTheSame(
                    @NonNull MessageUI oldMessage, @NonNull MessageUI newMessage) {
                // NOTE: if you use equals, your object must properly override Object#equals()
                // Incorrectly returning false here will result in too many animations.
                boolean isContentSame = newMessage.getId() == oldMessage.getId()
                        && Objects.equals(newMessage.getMessageText(), oldMessage.getMessageText())
                        && Objects.equals(newMessage.getPostedAt(), oldMessage.getPostedAt())
                        && Objects.equals(newMessage.getStatus(), oldMessage.getStatus())
                        && Objects.equals(newMessage.getChatId(), oldMessage.getChatId())
                        && Objects.equals(newMessage.getLocalUrl(), oldMessage.getLocalUrl());
                return isContentSame;
            }
        };

我有点卡在这里。让我总结一下;我需要在我的recyclerview适配器中获取特定的物品,但是使用位置信息根本没有好处。

0 个答案:

没有答案