Добавление нескольких представлений в представление Recycler динамически

Я создаю приложение для чата, где мне нужно заполнить другой файл XML на основе messageType на странице чатов, где отображаются все разговоры с конкретным пользователем. Пример, если messageType - это изображение, которое я хочу заполнить другим xml, и если messageType - это видео, я хочу заполнить другой xml-файл и, аналогично, для текста и аудио каждый раз другой xml-файл. Однако в моем коде я заполнил один общий xml в методе onCreateViewHolder. MessageType извлекается из класса модели.

Любая помощь, как это сделать?

Заранее спасибо!!

2 ответа

Вы можете сделать это, используя различные значения типа элемента для каждого messageType, Корень этой логики - адаптер getItemViewType() Перезвоните:

@Override
public int getItemViewType(int position) {
    if (isImage(position)) {
        return R.layout.layout_for_image;
    } else if (isVideo(position) {
        return R.layout.layout_for_video;
    } else {
        // and so on...
    }
}

Мы используем трюк здесь: getItemViewType() заботится только о том, чтобы вы вернули int; его не волнует, что такое фактические значения int, поэтому мы используем идентификаторы макета в качестве возвращаемого значения. Это хорошо, потому что это означает, что вам не нужно определять дополнительные константы или отслеживать, какой тип представления соответствует 0 и что идет с 1, так далее.

Вы также должны создать другой вид ViewHolder для каждого типа просмотра. viewType параметр, передаваемый этому методу, будет иметь любое значение, которое вы вернули из getItemViewType()и так как мы вернули идентификаторы макета, мы можем просто накачать любое значение, которое мы получим. Конечно, мы все еще должны передать это право ViewHolder, но все же это немного облегчает ситуацию:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View itemView = inflater.inflate(viewType, parent, false);

    switch (viewType) {
        case R.layout.layout_for_image: return new ImageViewHolder(itemView);
        case R.layout.layout_for_video: return new VideoViewHolder(itemView);
        ...
    }
}

Последний кусок является обязательным:

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    switch (holder.getItemViewType()) {
        case R.layout.layout_for_image:
            bindImage(holder, position);
            break;

        case R.layout.layout_for_video:
            bindVideo(holder, position);
            break;

        ...
    }
}

Переопределите getViewType(int index) и верните разные значения для типов объектов, затем вы получите его в onCreateViewHolder и наполните правильное представление различными ViewHolders, тот же тип держателя будет возвращен в onBindViewHolder для равных viewTypes.