11

Мне нужно в зависимости от типа объекта(записи), заполнить RecyclerView разными view, раньше когда я делал это с помощью ListView у меня получалось, а тут я даже не знаю как это организовать, в onCreateViewHolder сразу создается view но без учета текущей позиции, следовательно я не могу несколько разных view там создать.

Как это можно организовать?

zTrap
  • 2,720
  • 11
  • 31
wpbloger
  • 453
  • 3
  • 14

3 Answers3

16

Для создания айтемов разного вида необходимо переопределить метод адаптера getItemViewType(), который будет в зависимости от условия определять, айтем какого вида требуется в данной позиции. В RecyclerView этот механизм был улучшен и метод onCreateViewHolder() возвращает значение ViewType - какой тип айтема требуется в данной позиции:

class MyAdapter extends RecyclerView.Adapter <MyAdapter.ItemHolder> {

    private final int TYPE_ITEM1 = 0;
    private final int TYPE_ITEM2 = 1;

    public MyAdapter () {
     // конструктор адаптера
    }

    @Override
    public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v;

        switch (viewType) {
         // инфлейтим нужную разметку в зависимости от того,
         // какой тип айтема нужен в данной позиции

            case TYPE_ITEM1:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
                break;
            case TYPE_ITEM2:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item2, parent, false);
        }
      return new ItemHolder(v);
    }

    @Override
    public void onBindViewHolder( ItemHolder holder, int position) {

     // Получаем тип айтема в данной позиции для заполнения его данными
        int type = getItemViewType(position);

        switch (type) {
            case TYPE_ITEM1:
                holder.mText1.setText("биндим данные в айтем типа 1");
                break;  
            case TYPE_ITEM2:
                holder.mText2.setText("биндим данные в айтем типа 2");
                break;
        }
    }

    @Override
    public int getItemViewType(int position) {
         // условие для определения айтем какого типа выводить в конкретной позиции
        if (position == <условие>) return TYPE_ITEM1;
        return TYPE_ITEM2;
    }

public static class ItemHolder extends RecyclerView.ViewHolder{

    TextView mText1;
    TextView mText2;

    public ItemHolder(View v) {
        super(v);

        mText1 = (TextView) v.findViewById(R.id.text1);
        mText2 = (TextView) v.findViewById(R.id.text2);
    }
 }
pavlofff
  • 36,765
  • А есть возможность использовать разные Holder'ы что бы не сваливать все в один? – wpbloger Nov 28 '15 at 14:11
  • @wpbloger Вы можете использовать любое нужное вам количество холдеров и прочие оптимизации и паттерны. Это лишь минимальный пример, основная цель которого - принцип использования метода getItemViewType() – pavlofff Nov 28 '15 at 14:27
  • 1
    @wpbloger Смотрите, скажем, этот пример – pavlofff Nov 28 '15 at 14:48
  • А что если я получаю данные списками? Поясню: private List android;
    public DataAdapter(List<TextNumeric> android) {
        this.android = android;
    }
    

    Только сейчас уже получаю не один тип, а два, как в Вашем примере. Подскажите как возможно подкорректировать пожалуйста.

    – Morozov Sep 08 '16 at 07:20
  • Мда, неудобно, что разработчики сделали возвращаемое значение типа int... – Боков Глеб Apr 24 '17 at 09:26
2

Можно писать свой адаптер, как ответил @pavlofff, можно воспользоваться готовыми библиотеками: https://github.com/vivchar/RendererRecyclerViewAdapter https://github.com/sockeqwe/AdapterDelegates

Vitaly
  • 494
1

У кого остались вопросы по примеру, приведённому выше, (или кто-то хочет более детально разобраться), в дополнение к примеру ссылку Вам!

Morozov
  • 2,756
  • Не является ответом на вопрос. Чтобы оставить свои замечания или попросить у автора внести уточнения, оставьте комментарий к соответствующему сообщению. - Из очереди проверок – Denis Bubnov Sep 08 '16 at 11:02
  • скинул ссылку где более подробно освящается вопрос(мне помогло, решил поделиться). – Morozov Sep 08 '16 at 11:04