it-swarm.com.ru

Recyclerview и обработка различных типов инфляции строк

Я пытаюсь работать с новой RecyclerView, но я не смог найти пример RecyclerView с различными типами строк/просмотров карт, которые были раздуты.

С ListView я переопределяю getViewTypeCount и getItemViewType, для обработки разных типов строк.

Должен ли я сделать это как «старый» способ или я должен сделать что-то с LayoutManager? Мне было интересно, если кто-то может указать мне правильное направление. Потому что я могу найти примеры только с одним типом.

Я хочу иметь список немного разных карт. Или я должен просто использовать scrollView с cardViews внутри него ... сделать это без адаптера и recyclerView?

120
Lokkio

Обработка логики строк/разделов, аналогичной UITableView в iOS, не так проста в Android, как в iOS, однако при использовании RecyclerView - гибкость того, что вы можете сделать, гораздо выше.

В конце концов, все зависит от того, как вы выясните, какой тип отображения вы отображаете в адаптере. Как только вы это выяснили, все должно быть легко (не совсем, но, по крайней мере, вы разберетесь).

Адаптер предоставляет два метода, которые вы должны переопределить:

getItemViewType(int position)

Реализация этого метода по умолчанию всегда будет возвращать 0, указывая, что существует только 1 тип представления. В вашем случае это не так, поэтому вам нужно найти способ определить, какая строка соответствует какому типу представления. В отличие от iOS, которая управляет этим для вас со строками и разделами, здесь у вас будет только один индекс, и вам нужно будет использовать свои навыки разработчика, чтобы знать, когда позиция соотносится с заголовком раздела, а когда - с нормальный ряд.

createViewHolder(ViewGroup parent, int viewType)

В любом случае вам необходимо переопределить этот метод, но обычно люди просто игнорируют параметр viewType. В зависимости от типа представления вам нужно накачать правильный ресурс макета и соответственно создать свой держатель представления. RecyclerView будет обрабатывать переработку различных типов представлений таким образом, чтобы избежать столкновения разных типов представлений.

Если вы планируете использовать LayoutManager по умолчанию, такой как LinearLayoutManager, вам будет хорошо. Если вы планируете создать собственную реализацию LayoutManager, вам придется работать немного усерднее. Единственный API, с которым вам действительно нужно работать, это findViewByPosition(int position), который дает заданное представление в определенной позиции. Поскольку вы, вероятно, захотите расположить его по-разному в зависимости от того, что type this view, у вас есть несколько вариантов:

  1. Обычно при использовании шаблона ViewHolder вы устанавливаете тег представления с помощью держателя вида. Вы можете использовать это во время выполнения в менеджере компоновки, чтобы выяснить, к какому типу относится представление, добавив в держатель представления поле, выражающее это.

  2. Поскольку вам понадобится функция, которая определяет, какая позиция соотносится с тем или иным типом представления, вы также можете сделать этот метод как-то глобально доступным (возможно, одноэлементный класс, который управляет данными?), А затем вы можете просто запросить тот же метод в соответствии с позиция.

Вот пример кода:

// in this sample, I use an object array to simulate the data of the list. 
// I assume that if the object is a String, it means I should display a header with a basic title.
// If not, I assume it's a custom model object I created which I will use to bind my normal rows.
private Object[] myData;

public static final int ITEM_TYPE_NORMAL = 0;
public static final int ITEM_TYPE_HEADER = 1;

public class MyAdapter extends Adapter<ViewHolder> {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        if (viewType == ITEM_TYPE_NORMAL) {
            View normalView = LayoutInflater.from(getContext()).inflate(R.layout.my_normal_row, null);
            return new MyNormalViewHolder(normalView); // view holder for normal items
        } else if (viewType == ITEM_TYPE_HEADER) {
            View headerRow = LayoutInflater.from(getContext()).inflate(R.layout.my_header_row, null);
            return new MyHeaderViewHolder(headerRow); // view holder for header items
        }
    }


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

        final int itemType = getItemViewType(position);

        if (itemType == ITEM_TYPE_NORMAL) {
            ((MyNormalViewHolder)holder).bindData((MyModel)myData[position]);
        } else if (itemType == ITEM_TYPE_HEADER) {
            ((MyHeaderViewHolder)holder).setHeaderText((String)myData[position]);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (myData[position] instanceof String) {
            return ITEM_TYPE_HEADER;
        } else {
            return ITEM_TYPE_NORMAL;
        }
    }

    @Override
    public int getItemCount() {
        return myData.length;
    }
}

Вот пример того, как должны выглядеть эти держатели:

public MyHeaderViewHolder extends ViewHolder {

    private TextView headerLabel;    

    public MyHeaderViewHolder(View view) {
        super(view);

        headerLabel = (TextView)view.findViewById(R.id.headerLabel);
    }

    public void setHeaderText(String text) {
        headerLabel.setText(text);
    }    
}


public MyNormalViewHolder extends ViewHolder {

    private TextView titleLabel;
    private TextView descriptionLabel;    

    public MyNormalViewHolder(View view) {
        super(view);

        titleLabel = (TextView)view.findViewById(R.id.titleLabel);
        descriptionLabel = (TextView)view.findViewById(R.id.descriptionLabel);
    }

    public void bindData(MyModel model) {
        titleLabel.setText(model.getTitle());
        descriptionLabel.setText(model.getDescription());
    }    
}

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

// Assume names & descriptions are non-null and have the same length.
// Assume names are alphabetized
private void processDataSource(String[] names, String[] descriptions) {
    String nextFirstLetter = "";
    String currentFirstLetter;

    List<Object> data = new ArrayList<Object>();

    for (int i = 0; i < names.length; i++) {
        currentFirstLetter = names[i].substring(0, 1); // get the 1st letter of the name

        // if the first letter of this name is different from the last one, add a header row
        if (!currentFirstLetter.equals(nextFirstLetter)) {
            nextFirstLetter = currentFirstLetter;
            data.add(nextFirstLetter);
        }

        data.add(new MyModel(names[i], descriptions[i]));
    }

    myData = data.toArray();
}

Этот пример решает довольно конкретную проблему, но я надеюсь, что это даст вам хороший обзор того, как обрабатывать различные типы строк в утилизаторе, и позволит вам внести необходимые изменения в ваш собственный код в соответствии с вашими потребностями.

190
Gil Moshayof

Хитрость заключается в том, чтобы создать подклассы ViewHolder и затем привести их.

public class GroupViewHolder extends RecyclerView.ViewHolder {
    TextView mTitle;
    TextView mContent;
    public GroupViewHolder(View itemView) {
        super (itemView);
        // init views...
    }
}

public class ImageViewHolder extends RecyclerView.ViewHolder {
    ImageView mImage;
    public ImageViewHolder(View itemView) {
        super (itemView);
        // init views...
    }
}

private static final int TYPE_IMAGE = 1;
private static final int TYPE_GROUP = 2;  

А затем во время выполнения сделайте что-то вроде этого:

@Override
public int getItemViewType(int position) {
    // here your custom logic to choose the view type
    return position == 0 ? TYPE_IMAGE : TYPE_GROUP;
}

@Override
public void onBindViewHolder (ViewHolder viewHolder, int i) {

    switch (viewHolder.getItemViewType()) {

        case TYPE_IMAGE:
            ImageViewHolder imageViewHolder = (ImageViewHolder) viewHolder;
            imageViewHolder.mImage.setImageResource(...);
            break;

        case TYPE_GROUP:
            GroupViewHolder groupViewHolder = (GroupViewHolder) viewHolder;
            groupViewHolder.mContent.setText(...)
            groupViewHolder.mTitle.setText(...);
            break;
    }
}

Надеюсь, поможет.

108
ticofab

По словам Гила, отличный ответ я решил путем переопределения getItemViewType, как объяснил Гил. Его ответ великолепен и должен быть отмечен как правильный. В любом случае я добавляю код для достижения результата:

В вашем адаптере утилизатора:

@Override
public int getItemViewType(int position) {
    int viewType = 0;
    // add here your booleans or switch() to set viewType at your needed
    // I.E if (position == 0) viewType = 1; etc. etc.
    return viewType;
}

@Override
public FileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == 0) {
        return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout_for_first_row, parent, false));
    }

    return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_other_rows, parent, false));
}

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

31
iGio90

Это довольно сложно, но очень сложно, просто скопируйте приведенный ниже код, и все готово

package com.yuvi.sample.main;

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ImageView;
import Android.widget.TextView;


import com.yuvi.sample.R;

import Java.util.List;

/**
 * Created by yubraj on 6/17/15.
 */

public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.MainViewHolder> {
    List<MainOption> mainOptionlist;
    Context context;
    private static final int TYPE_PROFILE = 1;
    private static final int TYPE_OPTION_MENU = 2;
    private int selectedPos = 0;
    public NavDrawerAdapter(Context context){
        this.mainOptionlist = MainOption.getDrawableDataList();
        this.context = context;
    }

    @Override
    public int getItemViewType(int position) {
        return (position == 0? TYPE_PROFILE : TYPE_OPTION_MENU);
    }

    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case TYPE_PROFILE:
                return new ProfileViewHolder(LayoutInflater.from(context).inflate(R.layout.row_profile, parent, false));
            case TYPE_OPTION_MENU:
                return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.row_nav_drawer, parent, false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(MainViewHolder holder, int position) {
        if(holder.getItemViewType() == TYPE_PROFILE){
            ProfileViewHolder mholder = (ProfileViewHolder) holder;
            setUpProfileView(mholder);
        }
        else {
            MyViewHolder mHolder = (MyViewHolder) holder;
            MainOption mo = mainOptionlist.get(position);
            mHolder.tv_title.setText(mo.title);
            mHolder.iv_icon.setImageResource(mo.icon);
            mHolder.itemView.setSelected(selectedPos == position);
        }
    }

    private void setUpProfileView(ProfileViewHolder mholder) {

    }

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




public class MyViewHolder extends MainViewHolder{
    TextView tv_title;
    ImageView iv_icon;

    public MyViewHolder(View v){
        super(v);
        this.tv_title = (TextView) v.findViewById(R.id.tv_title);
        this.iv_icon = (ImageView) v.findViewById(R.id.iv_icon);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Redraw the old selection and the new
                notifyItemChanged(selectedPos);
                selectedPos = getLayoutPosition();
                notifyItemChanged(selectedPos);
            }
        });
    }
}
    public class ProfileViewHolder extends MainViewHolder{
        TextView tv_name, login;
        ImageView iv_profile;

        public ProfileViewHolder(View v){
            super(v);
            this.tv_name = (TextView) v.findViewById(R.id.tv_profile);
            this.iv_profile = (ImageView) v.findViewById(R.id.iv_profile);
            this.login = (TextView) v.findViewById(R.id.tv_login);
        }
    }

    public void trace(String tag, String message){
        Log.d(tag , message);
    }
    public class MainViewHolder extends  RecyclerView.ViewHolder {
        public MainViewHolder(View v) {
            super(v);
        }
    }


}

наслаждаться !!!!

14
yubaraj poudel

Мы можем добиться многократного просмотра одного RecyclerView снизу: -

Зависимости от Gradle, поэтому добавьте следующий код: -

compile 'com.Android.support:cardview-v7:23.0.1'
compile 'com.Android.support:recyclerview-v7:23.0.1'

RecyclerView в XML

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recyclerView"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"/>

Код активности

private RecyclerView mRecyclerView;
private CustomAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private String[] mDataset = {“Data - one ”, “Data - two”,
    “Showing data three”, “Showing data four”};
private int mDatasetTypes[] = {DataOne, DataTwo, DataThree}; //view types
 
...
 
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setLayoutManager(mLayoutManager);
//Adapter is created in the last step
mAdapter = new CustomAdapter(mDataset, mDataSetTypes);
mRecyclerView.setAdapter(mAdapter);

Первый XML

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/cardview"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_marginTop="@dimen/ten"
    Android:elevation="@dimen/hundered”
    card_view:cardBackgroundColor=“@color/black“>
 
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:padding=“@dimen/ten">
 
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text=“Fisrt”
            Android:textColor=“@color/white“ />
 
        <TextView
            Android:id="@+id/temp"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="@dimen/ten"
            Android:textColor="@color/white"
            Android:textSize="30sp" />
    </LinearLayout>
 
</Android.support.v7.widget.CardView>

Второй XML

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/cardview"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_marginTop="@dimen/ten"
    Android:elevation="100dp"
    card_view:cardBackgroundColor="#00bcd4">
 
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:padding="@dimen/ten">
 
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text=“DataTwo”
            Android:textColor="@color/white" />
 
        <TextView
            Android:id="@+id/score"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="@dimen/ten"
            Android:textColor="#ffffff"
            Android:textSize="30sp" />
    </LinearLayout>
 
</Android.support.v7.widget.CardView>

Третий XML

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/cardview"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_marginTop="@dimen/ten"
    Android:elevation="100dp"
    card_view:cardBackgroundColor="@color/white">
 
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:padding="@dimen/ten">
 
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text=“DataThree” />
 
        <TextView
            Android:id="@+id/headline"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="@dimen/ten"
            Android:textSize="25sp" />
 
        <Button
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="@dimen/ten"
            Android:id="@+id/read_more"
            Android:background="@color/white"
            Android:text=“Show More” />
    </LinearLayout>
 
</Android.support.v7.widget.CardView>

Теперь пришло время сделать адаптер, и это главное для отображения разных представлений -2 на одном и том же представлении переработчика, поэтому, пожалуйста, полностью проверьте этот код: -

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
    private static final String TAG = "CustomAdapter";
 
    private String[] mDataSet;
    private int[] mDataSetTypes;
 
    public static final int dataOne = 0;
    public static final int dataTwo = 1;
    public static final int dataThree = 2;
 
 
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View v) {
            super(v);
        }
    }
 
    public class DataOne extends ViewHolder {
        TextView temp;
 
        public DataOne(View v) {
            super(v);
            this.temp = (TextView) v.findViewById(R.id.temp);
        }
    }
 
    public class DataTwo extends ViewHolder {
        TextView score;
 
        public DataTwo(View v) {
            super(v);
            this.score = (TextView) v.findViewById(R.id.score);
        }
    }
 
    public class DataThree extends ViewHolder {
        TextView headline;
        Button read_more;
 
        public DataThree(View v) {
            super(v);
            this.headline = (TextView) v.findViewById(R.id.headline);
            this.read_more = (Button) v.findViewById(R.id.read_more);
        }
    }
 
 
    public CustomAdapter(String[] dataSet, int[] dataSetTypes) {
        mDataSet = dataSet;
        mDataSetTypes = dataSetTypes;
    }
 
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View v;
        if (viewType == dataOne) {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.weather_card, viewGroup, false);
 
            return new DataOne(v);
        } else if (viewType == dataTwo) {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.news_card, viewGroup, false);
            return new DataThree(v);
        } else {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.score_card, viewGroup, false);
            return new DataTwo(v);
        }
    }
 
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {
        if (viewHolder.getItemViewType() == dataOne) {
            DataOne holder = (DataOne) viewHolder;
            holder.temp.setText(mDataSet[position]);
        }
        else if (viewHolder.getItemViewType() == dataTwo) {
            DataThree holder = (DataTwo) viewHolder;
            holder.headline.setText(mDataSet[position]);
        }
        else {
            DataTwo holder = (DataTwo) viewHolder;
            holder.score.setText(mDataSet[position]);
        }
    }
 
    @Override
    public int getItemCount() {
        return mDataSet.length;
    }
 
   @Override
    public int getItemViewType(int position) {
        return mDataSetTypes[position];
    }
}

Вы можете проверить также эту ссылку для получения дополнительной информации.

3
duggu

Вы должны реализовать getItemViewType() метод в RecyclerView.Adapter. По умолчанию onCreateViewHolder(ViewGroup parent, int viewType) реализация viewType этого метода возвращает 0. Во-первых, вам нужен тип представления элемента в позиции для переработки вида, и для этого вы должны переопределить метод getItemViewType(), в котором вы можете передать viewType, который вернет вашу позицию элемента. Пример кода приведен ниже

@Override
public MyViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
    int listViewItemType = getItemViewType(viewType);
    switch (listViewItemType) {
         case 0: return new ViewHolder0(...);
         case 2: return new ViewHolder2(...);
    }
}

@Override
public int getItemViewType(int position) {   
    return position;
}

// and in the similar way you can set data according 
// to view holder position by passing position in getItemViewType
@Override
public void onBindViewHolder(MyViewholder viewholder, int position) {
    int listViewItemType = getItemViewType(position);
    // ...
}
2
Amandeep Rohila

Вы можете использовать библиотеку: https://github.com/vivchar/RendererRecyclerViewAdapter

mRecyclerViewAdapter = new RendererRecyclerViewAdapter(); /* included from library */
mRecyclerViewAdapter.registerRenderer(new SomeViewRenderer(SomeModel.TYPE, this));
mRecyclerViewAdapter.registerRenderer(...); /* you can use several types of cells */

Для каждого элемента вы должны реализовать ViewRenderer, ViewHolder, SomeModel:

ViewHolder - это простая подставка для просмотра представления переработчика.

SomeModel - это ваша модель с интерфейсом ItemModel

public class SomeViewRenderer extends ViewRenderer<SomeModel, SomeViewHolder> {

    public SomeViewRenderer(final int type, final Context context) {
        super(type, context);
    }

    @Override
    public void bindView(@NonNull final SomeModel model, @NonNull final SomeViewHolder holder) {
       holder.mTitle.setText(model.getTitle());
    }

    @NonNull
    @Override
    public SomeViewHolder createViewHolder(@Nullable final ViewGroup parent) {
        return new SomeViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.some_item, parent, false));
    }
}

Для более подробной информации вы можете посмотреть документацию.

1
Vitaly

Вы можете просто вернуть ItemViewType и использовать его. Смотрите ниже код:

@Override
public int getItemViewType(int position) {

    Message item = messageList.get(position);
    // return my message layout
    if(item.getUsername() == Message.userEnum.I)
        return R.layout.item_message_me;
    else
        return R.layout.item_message; // return other message layout
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(viewType, viewGroup, false);
    return new ViewHolder(view);
}
1
김영호

getItemViewType (int position) является ключом

На мой взгляд, отправная точка для создания такого рода recyclerView это знание этого метода. Поскольку этот метод не является обязательным для переопределить, поэтому он не виден в классе RecylerView по умолчанию что, в свою очередь, заставляет многих разработчиков (включая меня) задуматься, где начать. Как только вы узнаете, что этот метод существует, создайте такой RecyclerView будет легкой прогулкой.

Как это сделать ?

Вы можете создать RecyclerView с любым количеством различных представлений (ViewHolders). Но для лучшей читаемости давайте возьмем пример RecyclerView с двумя Viewholders.
Запомните эти 3 простых шага и вам будет хорошо идти. 

  • Переопределить public int getItemViewType(int position)
  • Возвращать различные ViewHolders на основе метода ViewType in OnCreateViewHolder ()
  • Заполнить представление на основе itemViewType в методе onBindViewHolder()

    Вот фрагмент кода для вас 

    public class YourListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private static final int LAYOUT_ONE= 0;
        private static final int LAYOUT_TWO= 1;
    
        @Override
        public int getItemViewType(int position)
        {
            if(position==0)
               return LAYOUT_ONE;
            else
               return LAYOUT_TWO;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            View view =null;
            RecyclerView.ViewHolder viewHolder = null;
    
            if(viewType==LAYOUT_ONE)
            {
               view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one,parent,false);
               viewHolder = new ViewHolderOne(view);
            }
            else
            {
               view = LayoutInflater.from(parent.getContext()).inflate(R.layout.two,parent,false);
               viewHolder= new ViewHolderTwo(view);
            }
    
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    
           if(holder.getItemViewType()== LAYOUT_ONE)
           {
               // Typecast Viewholder 
               // Set Viewholder properties 
               // Add any click listener if any 
           }
           else {
    
               ViewHolderOne vaultItemHolder = (ViewHolderOne) holder;
               vaultItemHolder.name.setText(displayText);
               vaultItemHolder.name.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View v) {
                       .......
                   }
               });
    
           }
    
       }
    
       /****************  VIEW HOLDER 1 ******************//
    
       public class ViewHolderOne extends RecyclerView.ViewHolder {
    
           public TextView name;
    
           public ViewHolderOne(View itemView) {
           super(itemView);
           name = (TextView)itemView.findViewById(R.id.displayName);
           }
       }
    
    
      //****************  VIEW HOLDER 2 ******************//
    
      public class ViewHolderTwo extends RecyclerView.ViewHolder{
    
           public ViewHolderTwo(View itemView) {
           super(itemView);
    
               ..... Do something
           }
      }
    }
    
0
Rohit Singh

Вы можете использовать эту библиотеку:
https://github.com/kmfish/MultiTypeListViewAdapter (написано мной)

  • Лучше повторно использовать код одной ячейки
  • Лучшее расширение
  • Лучше отделить

Установочный адаптер:

adapter = new BaseRecyclerAdapter();
adapter.registerDataAndItem(TextModel.class, LineListItem1.class);
adapter.registerDataAndItem(ImageModel.class, LineListItem2.class);
adapter.registerDataAndItem(AbsModel.class, AbsLineItem.class);

Для каждой позиции:

public class LineListItem1 extends BaseListItem<TextModel, LineListItem1.OnItem1ClickListener> {

    TextView tvName;
    TextView tvDesc;


    @Override
    public int onGetLayoutRes() {
        return R.layout.list_item1;
    }

    @Override
    public void bindViews(View convertView) {
        Log.d("item1", "bindViews:" + convertView);
        tvName = (TextView) convertView.findViewById(R.id.text_name);
        tvDesc = (TextView) convertView.findViewById(R.id.text_desc);

        tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != attachInfo) {
                    attachInfo.onNameClick(getData());
                }
            }
        });
        tvDesc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != attachInfo) {
                    attachInfo.onDescClick(getData());
                }
            }
        });

    }

    @Override
    public void updateView(TextModel model, int pos) {
        if (null != model) {
            Log.d("item1", "updateView model:" + model + "pos:" + pos);
            tvName.setText(model.getName());
            tvDesc.setText(model.getDesc());
        }
    }

    public interface OnItem1ClickListener {
        void onNameClick(TextModel model);
        void onDescClick(TextModel model);
    }
}
0
kmfish