Страницы

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

суббота, 11 января 2020 г.

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

#android #recyclerview #header


Мне приходит JSON массив с сервера с датой и количеством сообщений. Мне нужно сделать
список в котором дата будет находиться перед началом сообщений этой даты. Никак не
пойму как можно научить адаптер строить такой список. 

Помогите, покажите пальцем, куда копать? 

Есть примерный способ реализации:


Завести массив с датами сообщений в формате HH:mm
???

    


Ответы

Ответ 1



Организация данных такая, что нужно распарсить 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); } } Естественно, разметки нужно оформить покрасивее как то, выделить дату можно другим фоном или другое. Данный пример - только идея.

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

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