RecyclerView onCreateViewHolder Return type Incompatible with multiple custom watch ViewHolders

I am trying to use multiple ViewHolders in a RecyclerView to swap these views at runtime. I created two classes that extend RecyclerView.ViewHolder:

MenuItemViewHolder

public class MenuItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView menuItemText; public ImageView menuItemPhoto; public RecyclerViewAdapter rva; public MenuItemViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); rva = caller; menuItemText = (TextView) itemView.findViewById(R.id.grid_text); menuItemPhoto = (ImageView) itemView.findViewById(R.id.grid_image); } @Override public void onClick(View view) { Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show(); } } 

SelectedItemViewHolder

 public class SelectedItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView menuItemText; public ImageView menuItemPhoto; public RecyclerViewAdapter rva; public SelectedItemViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); menuItemText = (TextView) itemView.findViewById(R.id.grid_text_full); menuItemPhoto = (ImageView) itemView.findViewById(R.id.grid_image_full); } @Override public void onClick(View view) { Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show(); } } 

They are called in my function of the RecyclerViewAdapter class onCreateViewHolder:

RecyclerViewAdapter onCreateViewHolder

 // Create new views (invoked by the layout manager) @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case 0: View gridItemLayout = LayoutInflater.from(parent.getContext()) .inflate(R.layout.grid_single, parent, false); // set the view size, margins, paddings and layout parameters MenuItemViewHolder vh = new MenuItemViewHolder(gridItemLayout); case 2: View selectedItemLayout = LayoutInflater.from(parent.getContext()) .inflate(R.layout.grid_single_full, parent, false); // set the view size, margins, paddings and layout parameters SelectedItemViewHolder sivh = new SelectedItemViewHolder(selectedItemLayout); return sivh; } } 

When I try to run the code, I get this error:

Error: (48, 36) error: onCreateViewHolder (ViewGroup, int) in the RecyclerViewAdapter cannot override onCreateViewHolder (ViewGroup, int) in the return type of the adapter ViewHolder is not compatible with MenuItemViewHolder, where VH is a variable of the type: VH extends ViewHolder declared in the class Adapter

So the problem is that onCreateViewHolder does not accept my custom classes as inherited from RecyclerView.ViewHolder. I am using Android Studio, so there may be a problem. I am puzzled since I thought Java inheritance would handle this without any problems. Can anyone suggest a solution?

Edit: When I change the return type of onCreateViewHolder to MenuItemViewHolder with only one VH, everything works fine. However, this does not work when I have several VH classes that can be replaced at any time.

+12
source share
2 answers

RecyclerView.Adapter is a parameterized class that takes one type of ViewHolder . Your definition probably looks like this:

 public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MenuItemViewHolder> 

It should be:

 public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 

Remember to also have the correct definition for onBindViewHolder . You also need to override getItemViewType .

+15
source

Full working code

For those who want a full working code. There you are.

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

Read more

You can read more about creating a RecyclerView with multiple ViewHolders.

0
source

All Articles