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