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

    @bakir13
    Для обработки событий от вьюшек в RecyclerView не предусмотрены специальные методы как у ListView (setOnItemClickListener или setOnItemSelectedListener).
    Обработка событий делается вручную через привязывание соответствующего слушателя к нужному вью. Позиция нажатия получается через метод ViewHolder.getAdapterPosition(), который возвращает позицию, которую отображает холдер. Но, так как RecyclerView обрабатывает обновления адаптера асинхронно, то может произойти такая ситуация, что то что отображается на экране может не соответствовать содержимому адаптера. Если такая ситуация происходит, то ViewHolder.getAdapterPosition() возвращает значение RecyclerView.NO_POSTION.
    Получается что-то вроде такого:
    class MessageAdapter extends RecyclreView.Adapter<MessageAdapter.ViewHolder> {
    
        private OnItemClickListener<Message> onItemClickListener;
    
        ...
    
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
            View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_of_rec_m, viewGroup, false);
            ViewHolder holder = ViewHolder(itemView);
            // сетим слушателя нажатий на нужный компонент
            holder.itemView.setOnClickListener(v -> {
                // получаем позицию в адаптере, которой соответсвует холдер
                int position = holder.getAdapterPosition();
                // если холдер соответсвует какой-либо позиции в адаптере
                if (position != RecyclerView.NO_POSITION) {
                    // уведомляем слушателя о нажатии
                    fireItemClicked(position, messageList.get(position));
                }
            });
        }
    
        private void fireItemClicked(int position, Message item) {
            if (onItemClickListener != null) {
                onItemClickListener.onItemClicked(position, item);
            }
        }
    
        ...
        // суда подписываемся активитей, фрагментом, перезнтером или чем нибудь еще
        public void setOnItemClickListener(OnItemClickListener<Message> listener) {
            onItemClickListener = listener;
        }
    
         // реализуем подписчиком
        public interface OnItemClickListener<T> {
            void onItemClicked(int position, T item);
        }
        
    }


    P.S.: ViewHolder лучше сделать статическим, что бы избежать возможных утечек памяти.
    Ответ написан
    Комментировать