it-swarm.com.de

Recyclerview und Umgang mit verschiedenen Arten der Reiheninflation

Ich versuche, mit der neuen RecyclerView zu arbeiten, aber ich konnte kein Beispiel für eine RecyclerView finden, bei der verschiedene Arten von Zeilen/Kartenansichten aufgebläht wurden.

Mit ListView überschreibe ich die getViewTypeCount und getItemViewType, um verschiedene Arten von Zeilen zu behandeln.

Soll ich es auf die "alte" Weise machen oder sollte ich etwas mit LayoutManager machen? Ich habe mich gefragt, ob mich jemand in die richtige Richtung weisen könnte. Weil ich nur Beispiele mit einem Typ finden kann.

Ich möchte eine Liste mit etwas anderen Karten. Oder sollte ich einfach eine scrollView mit cardViews darin verwenden ... ohne Adapter und recyclerView machen?

120
Lokkio

Die Handhabung der Zeilen-/Sektionslogik, die der von UITableView von iOS ähnelt, ist in Android nicht so einfach wie in iOS. Wenn Sie RecyclerView verwenden, ist die Flexibilität der Möglichkeiten jedoch viel größer.

Am Ende geht es darum, wie Sie herausfinden, welche Art von Ansicht Sie im Adapter anzeigen. Sobald Sie das herausgefunden haben, sollte es leicht sein zu segeln (nicht wirklich, aber zumindest haben Sie das sortiert).

Der Adapter macht zwei Methoden verfügbar, die Sie überschreiben sollten:

getItemViewType(int position)

Die Standardimplementierung dieser Methode gibt immer 0 zurück. Dies zeigt an, dass es nur einen Sichttyp gibt. In Ihrem Fall ist dies nicht der Fall, und Sie müssen einen Weg finden, um festzustellen, welche Zeile welchem ​​Ansichtstyp entspricht. Im Gegensatz zu iOS, das dies mit Zeilen und Abschnitten für Sie erledigt, haben Sie hier nur einen Index, auf den Sie sich verlassen können, und Sie müssen Ihre Entwicklerfähigkeiten einsetzen, um zu wissen, wann eine Position mit einer Abschnittsüberschrift korreliert und wann sie korreliert eine normale Reihe.

createViewHolder(ViewGroup parent, int viewType)

Sie müssen diese Methode sowieso überschreiben, aber normalerweise ignoriert man den viewType-Parameter. Je nach Ansichtstyp müssen Sie die korrekte Layoutressource aufblasen und Ihren Ansichtshalter entsprechend erstellen. RecyclerView übernimmt das Recycling verschiedener Ansichtstypen auf eine Weise, die das Zusammentreffen verschiedener Ansichtstypen verhindert.

Wenn Sie vorhaben, einen Standard-LayoutManager wie LinearLayoutManager zu verwenden, sollten Sie gut damit umgehen können. Wenn Sie planen, Ihre eigene LayoutManager-Implementierung zu erstellen, müssen Sie etwas härter arbeiten. Die einzige API, mit der Sie wirklich arbeiten müssen, ist findViewByPosition(int position), die eine bestimmte Ansicht an einer bestimmten Position gibt. Da Sie es wahrscheinlich je nach dem, was type dieser Ansicht ist, anders auslegen wollen, haben Sie einige Möglichkeiten:

  1. Normalerweise legen Sie bei Verwendung des ViewHolder-Musters das Tag der Ansicht mit dem Ansichtshalter fest. Sie können dies zur Laufzeit im Layout-Manager verwenden, um herauszufinden, um welchen Typ es sich bei der Ansicht handelt, indem Sie im View-Halter ein Feld hinzufügen, das dies ausdrückt.

  2. Da Sie eine Funktion benötigen, die bestimmt, welche Position mit welchem ​​Ansichtstyp korreliert, können Sie diese Methode auch irgendwie global zugänglich machen (möglicherweise eine Singleton-Klasse, die die Daten verwaltet?), Und Sie können einfach dieselbe Methode danach abfragen die Position.

Hier ist ein Codebeispiel:

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

Hier sehen Sie ein Beispiel, wie diese Ansichtshalter aussehen sollten:

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

In diesem Beispiel wird natürlich davon ausgegangen, dass Sie Ihre Datenquelle (myData) so erstellt haben, dass die Implementierung eines Adapters auf diese Weise vereinfacht wird. Als Beispiel zeige ich Ihnen, wie ich eine Datenquelle konstruiere, die eine Liste mit Namen und eine Kopfzeile für jedes Mal enthält, wenn sich der erste Buchstabe des Namens ändert (vorausgesetzt, die Liste ist alphabetisch) - ähnlich wie bei Kontakten Liste würde wie folgt aussehen:

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

In diesem Beispiel wird ein ziemlich spezifisches Problem gelöst. Ich hoffe, Sie erhalten dadurch einen guten Überblick über den Umgang mit verschiedenen Zeilentypen in einem Recycler und können die erforderlichen Anpassungen in Ihrem eigenen Code vornehmen, um Ihre Anforderungen zu erfüllen.

190
Gil Moshayof

Der Trick besteht darin, Unterklassen von ViewHolder zu erstellen und diese dann umzuwandeln.

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;  

Und dann zur Laufzeit so etwas tun:

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

Ich hoffe es hilft.

108
ticofab

Laut Gils großartiger Antwort löste ich das Problem durch Überschreiben des getItemViewType, wie von Gil beschrieben. Seine Antwort ist großartig und muss als richtig markiert werden. In jedem Fall füge ich den Code hinzu, um die Punktzahl zu erreichen:

In Ihrem Recycler-Adapter:

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

Auf diese Weise können Sie das benutzerdefinierte Layout für jede Zeile festlegen!

31
iGio90

Es ist ziemlich schwierig, aber so schwer, einfach den Code kopieren und fertig

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


}

genießen !!!!

14
yubaraj poudel

Wir können eine mehrfache Ansicht auf einzelne RecyclerView-Ansicht von unten erreichen: -

Abhängigkeiten von Gradle fügen Sie also den folgenden Code hinzu: -

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

RecyclerView in XML

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

Aktivitätscode

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

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

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

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

Nun ist es an der Zeit, einen Adapter zu erstellen. Dies ist vor allem für die Anzeige verschiedener -2-Ansichten in derselben Recycler-Ansicht erforderlich. Überprüfen Sie daher den folgenden Codefokus vollständig: -

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

Sie können auch dieses Link für weitere Informationen überprüfen.

3
duggu

Sie müssen die getItemViewType() Methode in RecyclerView.Adapter implementieren. Standardmäßig gibt die onCreateViewHolder(ViewGroup parent, int viewType)-Implementierung viewType dieser Methode 0 zurück. Zuerst benötigen Sie den Ansichtstyp des Elements an Position zum Zwecke des Ansichts-Recyclings und dafür müssen Sie die getItemViewType()-Methode überschreiben, in der Sie viewType übergeben können, die Ihre Position des Elements zurückgibt. Codebeispiel ist unten angegeben

@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

Sie können die Bibliothek verwenden: 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 */

Für jedes Element sollten Sie einen ViewRenderer, ViewHolder, SomeModel implementieren:

ViewHolder - es ist ein einfacher Ansichtshalter der Recycler-Ansicht.

SomeModel - es ist Ihr Modell mit ItemModel-Schnittstelle

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

Für weitere Details können Sie Dokumentationen anschauen.

1
Vitaly

Sie können ItemViewType einfach zurückgeben und verwenden. Siehe folgenden Code:

@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) ist der Schlüssel

Meiner Meinung nach der Ausgangspunkt für diese Art von RecyclerView ist das Wissen über diese Methode. Da diese Methode für .__ optional ist. überschreiben, daher ist es standardmäßig in der RecylerView-Klasse nicht sichtbar was wiederum viele Entwickler (einschließlich mir) fragt, wohin Start. Sobald Sie wissen, dass diese Methode existiert, erstellen Sie eine solche RecyclerView wäre ein Cakewalk.

Wie es geht ?

Sie können eine RecyclerView mit einer beliebigen Anzahl verschiedener Ansichten (ViewHolders) erstellen. Um die Lesbarkeit zu verbessern, nehmen wir ein Beispiel von RecyclerView mit zwei Viewholders.
Erinnere dich an diese 3 einfachen Schritte und du wirst gut sein. 

  • Public int getItemViewType(int position) überschreiben
  • Gibt andere ViewHolders basierend auf der ViewType in der __ onCreateViewHolder () - Methode zurück
  • Füllen Sie die Ansicht basierend auf der itemViewType-Methode in der onBindViewHolder()-Methode auf

    Hier ist ein Codeausschnitt für Sie 

    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

Sie können diese Bibliothek verwenden:
https://github.com/kmfish/MultiTypeListViewAdapter (von mir geschrieben)

  • Besser den Code einer Zelle wiederverwenden
  • Bessere Expansion
  • Bessere Entkopplung

Setup-Adapter:

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

Für jede Werbebuchung:

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