Страницы

Поиск по вопросам

вторник, 5 марта 2019 г.

RecyclerView - динамичное добавление header

Мне приходит JSON массив с сервера с датой и количеством сообщений. Мне нужно сделать список в котором дата будет находиться перед началом сообщений этой даты. Никак не пойму как можно научить адаптер строить такой список.
Помогите, покажите пальцем, куда копать?
Есть примерный способ реализации:
Завести массив с датами сообщений в формате HH:mm ???


Ответ

Организация данных такая, что нужно распарсить JSON в объекты модели, каждая модель будет содержать поле даты и поле записи. Коллекцию необходимо отсортировать по возрастанию даты.
Для начала нам понадобится два типа разметок. Первая будет отображать дату и запись (layout.header), вторая - только запись (layout.record). Разметка layout.header включает в себя разметку layout.record через include
layout.record:



layout.header:



Логика определения, какой тип View выводить основана на сравнении даты текущей записи и прошлой - если они не равны, то выводить заголовок с датой и записью, иначе только запись. Нулевой элемент обрабатывается отдельно и всегда содержит дату и запись.
Так же прошу обратить внимание на организацию блока switch - case в методе onBindViewHolder(). При выводе View с датой case выводит дату на разметку и "проваливается" на следующий case (нет оператора break), где на разметку выводится запись. Если заголовок не требуется, то на разметку дата не выводится (срабатывает второй case)
class SomeAdapter extends RecyclerView.Adapter {
private ArrayList mData; private final int TYPE_HEADER = 0; private final int TYPE_ITEM = 1;
public SomeAdapter (ArrayList data) { mData = data; }
@Override public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v;
switch (viewType) {
case TYPE_HEADER: v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false); break; default: v = LayoutInflater.from(parent.getContext()).inflate(R.layout.record, parent, false); } return new ItemHolder(v); }
@Override public void onBindViewHolder( ItemHolder holder, int position) {
int type = getItemViewType(position);
switch (type) {
case TYPE_HEADER: holder.mHeaderDate.setText(mData.get(position).getDate()));
case TYPE_ITEM: holder.mItemRecord.setText(mData.get(position).getRecord());
break; } }
@Override public int getItemCount() { return mData.size(); }
@Override public int getItemViewType(int position) {
if (isIdentType(position)) return TYPE_ITEM; return TYPE_HEADER; }
private boolean isIdentType (int position ){
if (!(position == 0)&&(mData.get(position).getDate()).equals(mData.get(position-1).getDate())) return true; return false; }
public static class ItemHolder extends RecyclerView.ViewHolder{
TextView mHeaderDate; TextView mItemRecord;
public ItemHolder(View v) { super(v);
mHeaderDate = (TextView) v.findViewById(R.id.date); mItemRecord = (TextView) v.findViewById(R.id.record); }
}
Естественно, разметки нужно оформить покрасивее как то, выделить дату можно другим фоном или другое. Данный пример - только идея.

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

Отправить комментарий