Recyclerview 및 다양한 유형의 행 인플레이션 처리 수 없습니다 . 로

나는 새로운 작업을 시도하고 RecyclerView있지만 RecyclerView다른 유형의 행 / 카드 뷰가 팽창 되는 예를 찾을 수 없습니다 .

ListViewi를을 무시 getViewTypeCount하고 getItemViewType행의 다른 유형을 처리하기위한.

“오래된”방식으로해야합니까, 아니면 뭔가해야 LayoutManager합니까? 누군가 나를 올바른 방향으로 안내 할 수 있는지 궁금했습니다. 한 가지 유형의 예만 찾을 수 있기 때문입니다.

약간 다른 카드 목록을 갖고 싶습니다. 아니면 내부에 a scrollView를 사용해야합니까 cardViews… 어댑터없이 만드십시오 recyclerView.



답변

iOS의 UITableView와 유사한 행 / 섹션 로직을 처리하는 것은 Android에서 iOS만큼 간단하지는 않지만 RecyclerView를 사용하면 수행 할 수있는 작업의 유연성이 훨씬 더 큽니다.

결국 어댑터에 표시되는보기 유형을 파악하는 방법이 전부입니다. 일단 당신이 그것을 이해했다면, 그것은 쉬운 항해가 될 것입니다 (실제로는 아니지만 적어도 당신은 그것을 분류 할 것입니다).

어댑터는 재정의해야하는 두 가지 메서드를 제공합니다.

getItemViewType(int position)

이 메서드의 기본 구현은 항상 0을 반환하여 뷰 유형이 1 개뿐임을 나타냅니다. 귀하의 경우에는 그렇지 않으므로 어떤 행이 어떤 뷰 유형에 해당하는지 주장하는 방법을 찾아야합니다. 행과 섹션을 사용하여이를 관리하는 iOS와 달리 여기에는 신뢰할 수있는 색인이 하나만 있으며, 위치가 섹션 헤더와 언제 상호 연관되는지, 정상적인 행.

createViewHolder(ViewGroup parent, int viewType)

어쨌든이 메서드를 재정의해야하지만 일반적으로 사람들은 viewType 매개 변수를 무시합니다. 보기 유형에 따라 올바른 레이아웃 리소스를 확장하고 그에 따라보기 홀더를 만들어야합니다. RecyclerView는 서로 다른 뷰 유형의 충돌을 방지하는 방식으로 서로 다른 뷰 유형 재활용을 처리합니다.

와 같은 기본 LayoutManager를 사용할 계획이라면 LinearLayoutManager가야합니다. 자신 만의 LayoutManager 구현을 계획하고 있다면 좀 더 열심히 작업해야합니다. 실제로 작업해야하는 유일한 API findViewByPosition(int position)는 특정 위치에서 주어진 뷰를 제공하는 것입니다. 이 뷰가 어떤 유형 인지에 따라 다르게 레이아웃하고 싶을 것이므로 몇 가지 옵션이 있습니다.

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

이 예제는 상당히 구체적인 문제를 해결하기 위해 제공되지만 리사이클 러에서 다양한 행 유형을 처리하는 방법에 대한 좋은 개요를 제공하고 필요에 맞게 코드에서 필요한 조정을 수행 할 수 있기를 바랍니다.


답변

트릭은 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;
    }
}

도움이 되었기를 바랍니다.


답변

Gil에 따르면 Gil이 설명한대로 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));
}

이렇게하면 모든 행에 대해 사용자 지정 레이아웃을 설정할 수 있습니다!


답변

꽤 까다 롭지 만 너무 어렵습니다. 아래 코드를 복사하면 완료됩니다.

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


}

즐겨 !!!!


답변

아래에서 단일 RecyclerView에 대한 여러 뷰를 얻을 수 있습니다.

Gradle에 대한 종속성이므로 아래 코드를 추가하십시오.

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

XML의 RecyclerView

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

자세한 내용 은이 링크 를 확인하십시오.


답변

.NET에서 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);
    // ...
}


답변

getItemViewType (int position)은 키입니다.

제 생각에 이런 종류의 recyclerView를 만드는 출발점은이 방법에 대한 지식입니다. 이 메서드는 재정의하는 선택 사항이므로 기본적으로 RecylerView 클래스에 표시되지 않으므로 많은 개발자 (나를 포함하여)가 어디서 시작해야할지 궁금해합니다. 이 방법이 존재한다는 것을 알고 나면 이러한 RecyclerView를 만드는 것은 쉽지 않을 것입니다.

여기에 이미지 설명 입력

어떻게하나요?

RecyclerView원하는 수의 다른 뷰 (ViewHolders)를 만들 수 있습니다 . 그러나 더 나은 가독성을 위해 RecyclerView두 개의 Viewholders.
3 가지 간단한 단계를 기억하십시오 .

  • public int 재정의 getItemViewType(int position)
  • ViewTypein onCreateViewHolder () 메서드를 기반으로 다른 ViewHolders 반환
  • onBindViewHolder()메서드 의 itemViewType을 기반으로 뷰 채우기

    다음은 귀하를위한 코드 스 니펫입니다.

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

GitHub 코드 :

다음은 여러 ViewHolders가있는 RecyclerView를 구현 한 프로젝트 입니다.