@Drew20
Недопрограммист Android))

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

У меня есть приложение в котором я получаю списки входящих и исходящие сообщений. Эти два списка размещены в RecyclerView которые в свою очередь находятся в фрагментах. Мне нужно при нажатии на определенное сообщение переходить на следующую активити где будет уже показано именно то сообщение на которое мы нажали в списке. Как это все должно происходить при нажатии на сообщение в списке я должен передавать на другую активити id сообщения которое мне приходит с сервера в массиве с сообщениями, а уже при открытии активити показа сообщения я буду отправлять запрос на сервер для показа всего сообщения. Мне не очень понятно как отловить нажатие на определенный элемент списка и еще более не понятно как потом из этого нажатия вытащить id сообщения. Так же я пробовал внедрить переход на другое активити но у меня почему-то не принимается инициализация intent. Вот код моего адаптера списка:
class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
    private RecyclerView recyclerViewItemClickListener;
    private List<Message> messageList;
    private Context ctx;

    MessageAdapter(List<Message> messageList, Context ctx) {
        this.messageList = messageList;
        this.ctx = ctx;

    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_of_rec_m, viewGroup, false);
        return new ViewHolder(v);

    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Message message = messageList.get(position);
        String id = String.valueOf(message.getId());
        holder.subject.setText(message.getSubject());
        holder.from.setText(message.getSender_name());
        holder.date.setText(message.getDate());
        holder.getAdapterPosition();

здесь я пытался вставить переход на другое активити
    }

    @Override
    public int getItemCount() {
        return messageList.size();
    }


    class ViewHolder extends RecyclerView.ViewHolder {
        final TextView from, subject, date;
        int position = 0;

        ViewHolder(View v) {
            super(v);
            subject = v.findViewById(R.id.subject);
            from = v.findViewById(R.id.from);
            date = v.findViewById(R.id.date);
            //id = v.findViewById(R.id.id);


            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                }
            });
        }
    }
}


Заранее спасибо за помощь, ценные советы и критику))
  • Вопрос задан
  • 5150 просмотров
Пригласить эксперта
Ответы на вопрос 4
@Ivan0206
Используй библиотеку ButterKnife. Недавно был похожий вопрос, поищи его, там всё расписано.
Ответ написан
@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 лучше сделать статическим, что бы избежать возможных утечек памяти.
Ответ написан
Комментировать
@red-barbarian
Ответ написан
Комментировать
MAGISTR_BRU
@MAGISTR_BRU
Я только учусь
Рекомендую к просмотру статью непосредственно от одного из разработчиков RecyclreView - https://proandroiddev.com/recyclerview-pro-tips-pa...

Ответ на ваш вопрос - пункт 2 в статье.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы