web-dev-qa-db-fra.com

Recyclage et traitement des différents types de gonflage des rangées

J'essaie de travailler avec la nouvelle RecyclerView, mais je n'ai pas trouvé d'exemple avec une RecyclerView avec différents types de lignes/vues de cartes gonflées.

Avec ListView, je remplace les getViewTypeCount et getItemViewType pour la gestion de différents types de lignes.

Suis-je censé le faire comme "à l'ancienne" ou devrais-je faire quelque chose avec LayoutManager? Je me demandais si quelqu'un pourrait m'indiquer la bonne direction. Parce que je ne peux trouver que des exemples avec un seul type.

Je veux avoir une liste de cartes légèrement différentes. Ou devrais-je simplement utiliser une scrollView avec cardViews à l'intérieur ... le rendre sans l'adaptateur et recyclerView?

120
Lokkio

Le traitement d'une logique de lignes/sections similaire à UITableView d'iOS n'est pas aussi simple sous Android que sous iOS. Cependant, lorsque vous utilisez RecyclerView, la flexibilité de vos tâches est bien plus grande.

En fin de compte, tout dépend de la manière dont vous déterminez le type de vue que vous affichez dans l'adaptateur. Une fois que vous avez compris, il devrait être facile de naviguer (pas vraiment, mais au moins vous aurez trié).

L'adaptateur expose deux méthodes que vous devez remplacer:

getItemViewType(int position)

L'implémentation par défaut de cette méthode retournera toujours 0, indiquant qu'il n'y a qu'un seul type de vue. Dans votre cas, ce n’est pas le cas et vous devrez donc trouver un moyen d’affirmer quelle ligne correspond à quel type de vue. Contrairement à iOS, qui gère cela pour vous avec des lignes et des sections, vous ne pouvez vous fier qu’à un seul index. Vous devez utiliser vos compétences de développeur pour savoir quand une position est corrélée à un en-tête de section et à quel une ligne normale.

createViewHolder(ViewGroup parent, int viewType)

Quoi qu'il en soit, vous devez remplacer cette méthode, mais généralement, les personnes ignorent simplement le paramètre viewType. Selon le type de vue, vous devez gonfler la ressource de présentation correcte et créer votre détenteur de vue en conséquence. RecyclerView gérera le recyclage de différents types de vues de manière à éviter tout conflit entre eux.

Si vous prévoyez d'utiliser un LayoutManager par défaut, tel que LinearLayoutManager, vous devriez être prêt à partir. Si vous envisagez de créer votre propre implémentation LayoutManager, vous devrez travailler un peu plus fort. La seule API avec laquelle vous devez vraiment travailler est findViewByPosition(int position), qui donne une vue donnée à une certaine position. Comme vous voudrez probablement le présenter différemment en fonction de ce que type est cette vue, vous avez quelques options:

  1. Habituellement, lorsque vous utilisez le modèle ViewHolder, vous définissez la balise de la vue avec le détenteur de la vue. Vous pouvez l'utiliser lors de l'exécution dans le gestionnaire de dispositions pour déterminer le type de la vue en ajoutant un champ dans le détenteur de la vue qui l'exprime.

  2. Comme vous avez besoin d’une fonction qui détermine quelle position correspond à quel type de vue, vous pouvez également rendre cette méthode globalement accessible (d’une classe singleton qui gère les données?), Puis vous pouvez simplement interroger la même méthode en fonction de la position.

Voici un exemple de code:

// 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;
    }
}

Voici un exemple de la présentation de ces affichages:

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());
    }    
}

Bien entendu, cet exemple suppose que vous avez construit votre source de données (myData) de manière à faciliter l'implémentation d'un adaptateur. À titre d'exemple, je vais vous montrer comment construire une source de données qui affiche une liste de noms et un en-tête pour chaque changement de la première lettre du nom (en supposant que la liste est alphabétisée) - de la même manière que les contacts la liste ressemblerait à ceci:

// 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();
}

Cet exemple permet de résoudre un problème assez spécifique, mais j'espère que cela vous donne une bonne idée de la gestion des différents types de lignes dans un recycleur et vous permet de faire les adaptations nécessaires dans votre propre code pour répondre à vos besoins.

190
Gil Moshayof

L'astuce consiste à créer des sous-classes de ViewHolder, puis de les lancer.

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;  

Et ensuite, à l'exécution, faites quelque chose comme ça:

@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;
    }
}

J'espère que ça aide.

108
ticofab

Selon Gil, j'ai trouvé une excellente réponse en remplaçant le getItemViewType comme expliqué par Gil. Sa réponse est excellente et doit être marquée comme correcte. Dans tous les cas, j'ajoute le code pour atteindre le score:

Dans votre adaptateur recycleur:

@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));
}

En faisant cela, vous pouvez définir n'importe quelle disposition personnalisée pour n'importe quelle ligne!

31
iGio90

C’est assez compliqué mais très difficile, copiez simplement le code ci-dessous et vous avez terminé

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);
        }
    }


}

prendre plaisir !!!!

14
yubaraj poudel

Nous pouvons obtenir une vue multiple sur un seul recycleur vu de la manière suivante: -

Dépendances sur Gradle alors ajoutez le code ci-dessous: -

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

RecyclerView en XML

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

Code d'activité

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);

Premier 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>

Deuxième 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>

Troisième 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>

Il est maintenant temps de créer un adaptateur et ceci est essentiel pour afficher différentes vues -2 sur la même vue du recycleur, veuillez donc vérifier attentivement le code correspondant: -

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];
    }
}

Vous pouvez aussi vérifier ceci lien pour plus d'informations.

3
duggu

Vous devez implémenter getItemViewType() method dans RecyclerView.Adapter. Par défaut, onCreateViewHolder(ViewGroup parent, int viewType) implementation viewType de cette méthode renvoie 0. Tout d’abord, vous avez besoin du type de vue de l’élément à la position pour les besoins du recyclage de la vue. Pour cela, vous devez outrepasser la méthode getItemViewType() dans laquelle vous pouvez transmettre viewType qui retournera votre position d’élément. Un exemple de code est donné ci-dessous

@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

Vous pouvez utiliser la bibliothèque: 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 */

Pour chaque élément, vous devez implémenter un ViewRenderer, ViewHolder, SomeModel:

ViewHolder - c'est un simple détenteur de vue de la vue recycleur.

SomeModel - c'est votre modèle avec l'interface 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));
    }
}

Pour plus de détails, vous pouvez consulter les documentations.

1
Vitaly

Vous pouvez simplement renvoyer ItemViewType et l'utiliser. Voir le code ci-dessous:

@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) est la clé

À mon avis, le point de départ pour créer ce type de recyclerView est la connaissance de cette méthode. Puisque cette méthode est facultative pour remplacez par conséquent, il n'est pas visible dans la classe RecylerView par défaut ce qui fait que de nombreux développeurs (y compris moi) se demandent où commencer. Une fois que vous savez que cette méthode existe, créez un tel fichier RecyclerView serait un jeu d'enfant.

Comment faire ?

Vous pouvez créer une RecyclerView avec un nombre quelconque de vues différentes (ViewHolders). Mais pour une meilleure lisibilité, prenons un exemple de RecyclerView avec deux Viewholders.
Rappelez-vous ces 3 simples étapes et vous serez bon aller. 

  • Remplacer public int getItemViewType(int position)
  • Renvoie différents ViewHolders basés sur la méthode ViewType dans OnCreateViewHolder ()
  • Remplir la vue en fonction de la méthode itemViewType dans onBindViewHolder()

    Voici un extrait de code pour vous 

    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

Vous pouvez utiliser cette bibliothèque:
https://github.com/kmfish/MultiTypeListViewAdapter (écrit par moi)

  • Mieux utiliser le code d'une cellule
  • Meilleure expansion
  • Mieux découpler

Adaptateur d'installation:

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

Pour chaque élément de campagne:

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