Добавление нескольких представлений в представление 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.