Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use one RecyclerView adapter for objects of different types using generics?

I have a RecyclerView which I want to be populated with String objects sometimes & with Product objects some other time. So I started creating its manager adapter this way:

// BaseSearchAdapter is the class that contains the 'List<T> mItems' member variable
public class SearchAdapter<T> extends BaseSearchAdapter<SearchAdapter.ViewHolder, T> {

    private Context mContext;

    public SearchAdapter(Context context, List<T> items) {
        mContext = context;
        mItems = new ArrayList<>(items);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        T item = mItems.get(position);
        holder.bind(item);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView textLabel;

        public ViewHolder(View v) {

        }

        public void bind(T item) {
            textLabel.setText(...); // How to handle T ?
        }
    }
}

where T could be String or Product according to the plan.

My question is how can I appropriately bind the data (whether it's a String or a Product) object to its corresponding view in this situation? Or is there a better way to handle this ?

like image 655
Mohammed Aouf Zouag Avatar asked Oct 15 '25 08:10

Mohammed Aouf Zouag


1 Answers

// BaseSearchAdapter is the class that contains the 'List<T> mItems' member variable
public class SearchAdapter<T> extends BaseSearchAdapter<SearchAdapter.ViewHolder<T>, T> {

    private Context mContext;
    private ViewHolderBinder<T> mBinder;

    public SearchAdapter(Context context, List<T> items, ViewHolderBinder<T> binder) {
        mContext = context;
        mItems = new ArrayList<>(items);
        mBinder = binder;
    }

    @Override
    public void onBindViewHolder(ViewHolder<T> holder, int position) {
        T item = mItems.get(position);
        holder.bind(item);
    }

    public static class ViewHolder<T> extends RecyclerView.ViewHolder {
        ViewHolderBinder<T> mBinder;

        TextView textLabel;


        public ViewHolder(View v, ViewHolderBinder<T> binder) {
            textLabel = (TextView)v.findViewById(R.id.text_label);
            this.mBinder = binder;
        }

        public void bind(T item) {
            binder.bind(this, item);
        }
    }

    public interface ViewHolderBinder<T> {
        void bind(ViewHolder<T> viewHolder, T item);
    }

    public static class StringViewHolderBinder implements ViewHolderBinder<String> {
        @Override
        public void bind(ViewHolder<String> viewHolder, String item) {
             viewHolder.textLabel.setText(item);
        }
    }

    public static class ProductViewHolderBinder implements ViewHolderBinder<Product> {
        @Override
        public void bind(ViewHolder<Product> viewHolder, Product item) {
             viewHolder.textLabel.setText(item.getName());
        }
    }
}
like image 165
EpicPandaForce Avatar answered Oct 16 '25 23:10

EpicPandaForce



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!