Well, if I understood correctly, you want to make a second adapter, one that provides lists of strings, a variable, so it supports different layouts based not on its position, but on some data from the main adapter (one of which contains sections). Therefore, overriding getItemViewType will not work, because the section data is contained in the main adapter, it does not even get there. So, the best and cleanest course is to use ... abstraction . Forget about a few viewers. Use it and tie to it. Custom views will provide both specific layout files and the installed controls included in them. The owner will do what he is intended to: save the ram by reusing the views. The advantage of this is that you can have a clean hierarchy that can grow over time, rather than with a large, bold adapter that becomes too complex to maintain. Here he is:
Since there is a lot of code for this, I took your sample project and modified it to ensure that I understood what you were trying to do. Here he is:
https://github.com/fcopardo/exampleCustomViewsInHolder/tree/master
Basic moments:
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> { private ArrayList<SingleItemModel> itemsList; private Context context; private String section; public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList, String sectionName) { this.itemsList = itemsList; this.context = context; this.section = sectionName; } @Override public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) { return new SingleItemRowHolder(RowFactory.getRow(context, section)); } @Override public void onBindViewHolder(SingleItemRowHolder holder, int i) { holder.setData(itemsList.get(i)); } @Override public int getItemCount() { return (null != itemsList ? itemsList.size() : 0); } public class SingleItemRowHolder extends RecyclerView.ViewHolder { protected AbstractRowElement rowElement; public SingleItemRowHolder(AbstractRowElement view) { super(view); this.rowElement = view; } public void setData(SingleItemModel singleItemModel){ rowElement.setItem(singleItemModel); } } }
This is a variable layout adapter. As you can see, it uses only one ViewHolder and factory to provide the instances you need.
public class RowFactory { public static AbstractRowElement getRow(Context context, String name){ switch (name){ case "Section 1": return new FullRowElement(context); case "Section 2": return new TextRowElement(context); case "Section 3": return new ImageRowElement(context); default: Log.e("inflate", name); return new FullRowElement(context); } } }
this provides custom views, each using a different layout, but working with the same data set based on the section header.
public abstract class AbstractRowElement extends CardView{ protected int layout = 0; protected SingleItemModel singleItemModel; public AbstractRowElement(Context context) { super(context); inflateBaseLayout(); } public AbstractRowElement(Context context, AttributeSet attrs) { super(context, attrs); inflateBaseLayout(); } public AbstractRowElement(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); inflateBaseLayout(); } protected void inflateBaseLayout() { this.setContainer(); if(this.layout != 0) { LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(layout, this, true); this.inflateComponents(); } } protected abstract void setContainer(); protected abstract void inflateComponents(); public void setItem(SingleItemModel itemModel){ this.singleItemModel = itemModel; this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext(), singleItemModel.getName()+"\n"+singleItemModel.getDescription(), Toast.LENGTH_SHORT).show(); } }); setData(singleItemModel); } public abstract void setData(SingleItemModel itemModel); }
Finally, this is the base view class for the adapter. Subclasses define the layout file to use and put the necessary data into the controls. The rest is pretty simple.
This would be entirely possible without custom views. You could just do something like:
int layoutFile = getLayoutForSection(section); View v = LayoutInflater.from(viewGroup.getContext()).inflate(layoutFile, null);
But since I donβt know how complicated the presentation you intend to create is, it is best to keep things beautifully separated. Enjoy!