I would suggest creating an abstract ViewHolder parent Class. It should have a static instantate method and a bindViewHolder method. Design the Adapter constructor to accept the ViewHolder parent Class object. When used, pass the child Class Object, and in onCreateViewHolder, use Reflection to create the child ViewHolder. When you get an onBindViewHolder, just pass it to the ViewHolder.
Here is a working example. I tested it, and it worked. I have removed non-essential code.
MainActivity.java
public class MainActivity extends AppCompatActivity
{
static class NameViewHolder extends MyViewHolder
{
TextView tv;
public static MyViewHolder instantate(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_recycler_item, parent, false);
MyViewHolder vh = new NameViewHolder(v);
return vh;
}
NameViewHolder(View v)
{
super(v);
tv = (TextView)v.findViewById(R.id.textView);
}
@Override
public void bindViewHolder(Object data)
{
tv.setText((String)data);
}
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView rv = (RecyclerView)findViewById(R.id.my_recycler_view);
rv.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(layoutManager);
ArrayList<String> data = new ArrayList();
for (int i = 1; i < 100; ++i)
data.add(Integer.toString(1000 + i));
MyAdapter adapter = new MyAdapter(data, NameViewHolder.class);
rv.setAdapter(adapter);
}
}
MyViewHolder.java
public abstract class MyViewHolder extends RecyclerView.ViewHolder
{
// The following has to be declared in sub class. As Java 7 does not support static interface, we commented it out here
//public static MyViewHolder instantate(ViewGroup parent, int viewType);
public MyViewHolder(View itemView)
{
super(itemView);
}
public abstract void bindViewHolder(Object data);
}
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>
{
List<Object> _data;
Class _holderClass;
MyAdapter(List data, Class holderClass)
{
_data = data;
_holderClass = holderClass;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
MyViewHolder vh = null;
try
{
Class[] cArg = {ViewGroup.class, int.class};
Method instantateMethod = _holderClass.getMethod("instantate", cArg);
vh = (MyViewHolder) instantateMethod.invoke(null, parent, viewType);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
holder.bindViewHolder(_data.get(position));
}
@Override
public int getItemCount()
{
return _data.size();
}
}