Может ли RecyclerView создавать более одного "представления" для каждого элемента?

TLDR:

Обычно в RecyclerView реализация, между Adapter и LayoutManager, существует соотношение один просмотр на элемент. Мы надеемся найти способ создать несколько представлений для каждого элемента.

Примечание. Пожалуйста, не путайте это с возможностью создавать различные типы представлений в зависимости от положения адаптера. Для простоты предположим, что существует только один тип просмотра.

Полный вопрос:

Для нашего проекта нам нужно создать список из нескольких столбцов. Список из нескольких столбцов визуально идентичен сетке, но имеет одно заметное отличие; в сетке (как это создано с GridLayoutAdapter), одна "клетка" (т.е. View / ViewHolder) представляет один элемент. В списке из нескольких столбцов одна строка представляет один элемент. Ячейки, составляющие эту строку, отображают разные свойства одного и того же элемента.

Например, скажем, у меня есть список из десяти объектов Foo, и Foo определяет пять свойств, которые мы хотим отобразить в столбцах. С точки зрения нашего набора данных, есть десять пунктов. С точки зрения LayoutManager однако существует пятьдесят (десять элементов (строк) умноженных на пять ячеек (столбцов) на строку / элемент.)

Подход, к которому я склоняюсь, заключается в создании RecyclerView.Adapter / RecyclerView.LayoutManager пара.

Во-первых, в моем подклассе адаптера, в дополнение к созданию свойства для хранения моих элементов данных, я также добавил свойство columnCount. Тогда в getItemCount() переопределить, вместо того, чтобы возвращать количество элементов, как обычно, я возвращаю количество элементов, умноженное на columnCount, вот так:

private List<Object> items;
public List<Object> getItems(){
    return items;
}
public void setItems(List<Object> items){
    this.items = items;
    notifyDataSetChanged();
}

private int columnCount = 1;
public int getColumnCount(){
    return columnCount;
}
public void setColumnCount(int columnCount){
    this.columnCount = Math.max(columnCount, 1);
    notifyDataSetChanged();
}

@Override public final int getItemCount(){
     return getItems().size() * getColumnCount();
}

Далее по моему RecyclerView.LayoutManager В подклассе я настраиваю его для захвата переданного адаптера, и если я могу привести его к конкретному типу адаптера, то я могу получить количество столбцов и использовать его для расчетов макета. Если это не тот тип адаптера, я просто отношусь к нему как к единственному столбцу.

Теперь, когда этот подход работает, он немного запутывает API getItemCount() больше не возвращает количество реальных элементов, а скорее количество просмотров, что может сбить пользователя с толку. (Я бы хотел, чтобы они назвали это getViewCount() вместо этого.) Это также означает, что LayoutManager работает только с определенным типом адаптера.

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

Мне интересно, если я подхожу к этому неправильно и / или есть ли API, который я уже могу использовать для этого. Есть ли такая вещь, или я на правильном подходе?

2 ответа

Вы можете достичь этого на уровне адаптера. Вам придется использовать эти три метода.

getItemViewType() 
onCreateViewHolder() 
onBindViewHolder()

Вот рабочий пример для вашей помощи. Дайте мне знать, если что-то не имеет смысла. Просто сделайте ваш элемент пейджером и добавьте несколько страниц элементов.

https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

У вас может быть несколько держателей видов с разными видами, поэтому в зависимости от типа вы можете использовать разные виды.

Другие вопросы по тегам