Как отслеживать выбранный элемент просмотра ресайклера?

У меня есть recyclerview с адаптером RecyclerView.Adapter. Элементы заполняются из базы данных комнат с помощью PagedList.

Я реализовал наложение режима контекстных действий на свою панель инструментов при долгом нажатии на элемент, точно так же, как это делает WhatsApp.

В держателе просмотра написано следующее 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 больше не соответствует действительности. Сдвигается вместе с количеством новых добавленных сообщений.

Я думаю, что лучшим способом было бы сохранить идентификатор элемента, поскольку он уникален для всех элементов адаптера. Однако notifyItemChanged использует позицию элемента, а не сам элемент. Кроме того, затем мне нужно выполнить поиск по всем элементам, чтобы получить выбранный элемент с помощью специального метода, который я должен написать, но в списке сообщений, который я использую, нет 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 ответов

Другие вопросы по тегам