0

У меня есть класс Event с параметрами, значение которых неважно. Я хочу показывать в RecyclerView массив Event. Далее, я хочу группировать эти Event и когда нужно показывать в виде [Заголовок, Событие1, Событие2], [Заголовок2, Событие3, Событие4].

Сначала я сделал главный класс MainItem, и Event и Header, преобразуемые в MainItem. Далее я сделал для них Holder'ы, и Адаптер, в котором с помощью двух ViewType'ов отображал массив List<MainItem>, в котором были либо только Event'ы, либо Header'ы и Event'ы.

Мне это показалось довольно костыльным, потому что Header и Event никак не были связаны. Я добавил в класс Header поле массив List<Event> для отображения событий, связанных с заголовком. Пришлось делать второй адаптер для RecyclerView класса Header и его Event'ов. В главном адаптере с помощью двух View Type я отображаю либо Заголовок с Событиями, либо просто События.

Меня смущает то, что у меня в итоге получилось два адаптера. Есть ли более оптимальный способ это всё организовать? Готовые пакеты типа Expandable Recycler View не предлагать.

Ниже привожу код:

Адаптер событий с заголовком:

public class EventAdapter extends RecyclerView.Adapter<EventHolder> {
private List&lt;EventItem&gt; subItemList;

EventAdapter(List&lt;EventItem&gt; subItemList) {
    this.subItemList = subItemList;
}

@NonNull
@Override
public EventHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_sub_item, viewGroup, false);
    return new EventHolder(view);
}

@Override
public void onBindViewHolder(@NonNull EventHolder subItemViewHolder, int i) {
    EventItem subItem = subItemList.get(i);

    subItemViewHolder.tvSubItemTitle.setText(subItem.getEventItemTitle());
    subItemViewHolder.tvSubItemDescr.setText(subItem.getEventItemDesc());
}

@Override
public int getItemCount() {
    return subItemList.size();
}

}

Главный адаптер:

public class MainAdapter extends RecyclerView.Adapter<MainViewHolder> {
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
private List&lt;MainItem&gt; itemList;
private Context context;

MainAdapter(Context context, List&lt;MainItem&gt; itemList) {
    this.context = context;
    this.itemList = itemList;
}

@NonNull
@Override
public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    //View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_item, viewGroup, false);
    View view;
    switch (i){
        case (Constants.ITEM_HEADER_TEXT_VIEWTYPE):
            view = LayoutInflater.from(context).inflate(R.layout.layout_item, viewGroup, false);
            return new HeaderHolder(view);
        case (Constants.ITEM_EVENT_TEXT_VIEWTYPE):
            view = LayoutInflater.from(context).inflate(R.layout.layout_sub_item, viewGroup, false);
            return new EventHolder(view);
        default: throw new IllegalArgumentException();
    }
}

@Override
public void onBindViewHolder(@NonNull MainViewHolder itemViewHolder, int i) {


    if (itemViewHolder.getItemViewType() == Constants.ITEM_HEADER_TEXT_VIEWTYPE){
        ((HeaderHolder)(itemViewHolder)).setData(itemList.get(i));
        HeaderItem item = itemList.get(i).getHeaderItem();


        // Create layout manager with initial prefetch item count
        LinearLayoutManager layoutManager = new LinearLayoutManager(
                ((HeaderHolder)(itemViewHolder)).rvSubItem.getContext(),
                LinearLayoutManager.VERTICAL,
                false
        );
        layoutManager.setInitialPrefetchItemCount(item.getEvents().size());

        // Create sub item view adapter
        EventAdapter subItemAdapter = new EventAdapter(item.getEvents());

        ((HeaderHolder)(itemViewHolder)).rvSubItem.setLayoutManager(layoutManager);
        ((HeaderHolder)(itemViewHolder)).rvSubItem.setAdapter(subItemAdapter);
        ((HeaderHolder)(itemViewHolder)).rvSubItem.setRecycledViewPool(viewPool);
    }
    else{
        ((EventHolder)(itemViewHolder)).setData(itemList.get(i));

    }


}

@Override
public int getItemCount() {
    return itemList.size();
}

@Override
public int getItemViewType(int position) {
    return itemList.get(position).getViewType();
}

}

  • Скорее всего да, дополнительный адаптер и RecyclerView внутри RecyclerView тут не нужны. Но, т.к. не до конца (по крайней мере мне) ясно чего именно вы хотите добиться - сложо предложить однозначное решение. Воможно вам стоит посмотреть в сторону https://github.com/sockeqwe/AdapterDelegates для удобного использования разных типов ячеек в одном списке. Ну и отдельно надо разобраться какая вам структура данных подойдёт для вашего случая. Возможно какая-то Map с сохранением порядка добавления элементов и типом Map<Header, List>. – ЮрийСПб Sep 06 '20 at 16:41
  • Но это не точно. Возможно вам как раз и надо 2 RecyclerView один в другом. – ЮрийСПб Sep 06 '20 at 16:41
  • Пример адаптера с выводом данных разного типа - https://ru.stackoverflow.com/a/798630/177345 – pavlofff Sep 07 '20 at 02:37
  • Ознакомлюсь с обеими рекомендациями. Спасибо. – Кирилл Химов Sep 07 '20 at 05:39

0 Answers0