Android — RecyclerView как обрабатывать ViewHolder с несколькими привязками

#android #android-recyclerview #android-viewbinding

#Android #android-recyclerview #android-привязка к просмотру

Вопрос:

Вот мой onBindViewHolder:

     @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        MessageModel message = values.get(position);
        switch (holder.getItemViewType()) {
            case VIEW_TYPE_VIDEO_SENT:
                ((VideoMessageHolder) holder).sentBinding.setMessageModel(message);
                break;
            case VIEW_TYPE_VIDEO_RECEIVED:
                ((VideoMessageHolder) holder).receivedBinding.setMessageModel(message);
                break;
        }
    }
  

Вот мой ViewHolder:

 

    private class VideoMessageHolder extends RecyclerView.ViewHolder {
        private RowRecyclerViewChatVideoMessageSentBinding sentBinding;
        private RowRecyclerViewChatVideoMessageReceivedBinding receivedBinding;

        VideoMessageHolder(RowRecyclerViewChatVideoMessageSentBinding binding) {
            super(binding.getRoot());
            this.sentBinding = binding;
        }

        VideoMessageHolder(RowRecyclerViewChatVideoMessageReceivedBinding binding) {
            super(binding.getRoot());
            this.receivedBinding = binding;
        }

    }
  

Я хочу иметь возможность получить соответствующую привязку, чтобы иметь возможность вносить изменения в представления внутри.

Комментарии:

1. pastebin.ubuntu.com/p/CKmDNMjYZV

2. Можете ли вы конкретно объяснить, что вам нужно? Выполняется ли сборка этого кода? Происходит сбой приложения? Скажите, что происходит против того, что вы хотите, чтобы произошло, и т.д.

3. Поскольку у меня есть два отдельных макета для каждого видеосообщения (один ориентирован налево, а другой — прямо в чате, больше ничего не отличается) Я хочу иметь возможность, например, вносить изменения в представления, изменения будут одинаковыми независимо от держателя представления rcvd или отправленного держателя представления, поэтому я не хочу создавать отдельные держатели представлений для каждого и переписывать код в них обоих….

Ответ №1:

Если у вас есть 2 разных макета для recyclerview, у вас должно быть 2 разных viewholder для него.

Сначала добавьте 2 разных ViewHolder для вашего адаптера

 private static int TYPE_SENT = 1;
private static int TYPE_RECEIVED = 2;

private class VideoSentHolder extends RecyclerView.ViewHolder {
    private RowRecyclerViewChatVideoMessageSentBinding sentBinding;

    VideoSentHolder(RowRecyclerViewChatVideoMessageSentBinding binding) {
        super(binding.getRoot());
        this.sentBinding = binding;
    }
}

private class VideoReceivedHolder extends RecyclerView.ViewHolder {
    private RowRecyclerViewChatVideoMessageReceivedBinding receivedBinding;

    VideoReceivedHolder(RowRecyclerViewChatVideoMessageReceivedBinding binding) {
        super(binding.getRoot());
        this.receivedBinding = binding;
    }

}
  

после этого установите тип элемента для адаптера с помощью этого метода

 @Override
public int getItemViewType(int position) {
    //Here you have to check condition for sent or received type
    if (TextUtils.isEmpty(list.get(position).isSent())) {
        return TYPE_SENT;

    } else {
        return TYPE_RECEIVED;
    }
}
  

в вашем onCreateViewHolder использовании 2 ViewHolder, как это:

 @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == TYPE_SENT) { // for Sent layout
        RowRecyclerViewChatVideoMessageSentBinding sentBinding;//Your sent binding
        return new VideoSentHolder(sentBinding);

    } else { // for received layout
        RowRecyclerViewChatVideoMessageReceivedBinding receivedBinding;//=your received binding
        return new VideoReceivedHolder(receivedBinding);
    }
}
  

и внутри вашего onBindViewHolder вы можете вызвать метод eash ViewHolder:

 @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
    MessageModel message = values.get(position);
    if (getItemViewType(position) == TYPE_SENT) {
        ((VideoSentHolder) viewHolder).sentBinding.setMessageModel(message);
    } else {
        ((VideoReceivedHolder) viewHolder).receivedBinding.setMessageModel(message);
    }
}
  

Комментарии:

1. Я знаю это, но я не хочу переписывать одну и ту же объемную загрузку кода в двух отдельных держателях, одного должно быть достаточно, как это происходит, если вы обрабатываете макеты традиционно (без использования привязки к просмотру) и имеете одинаковые идентификаторы для его представлений.