Reputation: 319
I've written a stock take app which at its core pulls data from a MySQL database using an API and creates different objects e.g Product, Order, Customer, when needed.
In my settings screen I have a button for each of these which goes to different activities where the relevant information is displayed in a RecyclerView and the user can add/edit/delete these objects.
Right now I have 3 adapters for the 3 RecyclerViews in these activities. I'm trying to create a single adapter as the functionality is almost identical.
My issue is in how to go about having one adapter that will accept e.g an ArrayList<Product>
or an ArrayList<Customer>
, or if that's even the best way to go about it. Just a point in the right direction would be much appreciated!
Upvotes: 1
Views: 1107
Reputation: 1728
According to your situation, you can either:
If you choose the second option (which you already use) you must make all Class inherit one Abtract Class. For example you can create one Class called Data, then Customer, Product, and Order will extends Data Class. Then you use ArrayList<Data>
in your adapter
Upvotes: 0
Reputation: 25267
You're thinking in right direction. I have already created a class that solves your problem:
public abstract class BaseRecyclerAdapter<T, VH extends BaseViewHolder> extends RecyclerView.Adapter<VH> {
private int mModelLayout;
private Class<VH> mViewHolderClass;
private List<T> mList = new ArrayList<>();
public BaseRecyclerAdapter(Class<VH> viewHolderClass, int modelLayout) {
mModelLayout = modelLayout;
mViewHolderClass = viewHolderClass;
}
public void setmList(List<T> mList) {
this.mList = mList;
}
@Override
public int getItemCount() {
return mList.size();
}
public T getItem(int position) {
return mList.get(position);
}
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
try {
Constructor<VH> constructor = mViewHolderClass.getConstructor(View.class);
return constructor.newInstance(view);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void onBindViewHolder(VH viewHolder, int position) {
T model = getItem(position);
populateViewHolder(viewHolder, model, position);
}
@Override
public int getItemViewType(int position) {
return mModelLayout;
}
abstract protected void populateViewHolder(VH viewHolder, T model, int position);
public void addItem(T t) {
int index = mList.size();
mList.add(index, t);
notifyItemInserted(index);
}
public void updateItem(int position, T t) {
mList.set(position, t);
notifyItemChanged(position);
}
public void removeItem(int position) {
mList.remove(position);
notifyItemRemoved(position);
}
public void setItems(List<T> items) {
mList = items;
notifyDataSetChanged();
}
public class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View view) {
super(view);
}
}
}
How to use it:
private BaseRecyclerAdapter<User, UserViewHolder> mBaseRecyclerAdapter = new BaseRecyclerAdapter<User, UserViewHolder>(UserViewHolder.class, R.layout.layout_list_item_friends) {
@Override
protected void populateViewHolder(UserViewHolder viewHolder, User model, int position) {
// You can do here whatever you want
}
};
Upvotes: 1