简体   繁体   中英

How to create base adapter which has type parameter that extends another class and implements an interface?

I have seen the answer to the question,

Java: how to create a generic class that requires a data type which extends a class and implements an interface?

So I attempted to create a base adapter for recyclerview. This is my complete code for the base adapter:

class BaseAdapter<T extends SugarRecord & ModelInterface> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {

    protected SparseArray<T> modelSparseArray;
    protected Context context;

    private int backgroundResource;



    public BaseAdapter(SparseArray<T> modelSparseArray, Context context) {
        this.modelSparseArray = modelSparseArray;
        this.context = context;
        setupBackgroundResource(context);
    }

    private void setupBackgroundResource(Context context){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.selectableItemBackground, typedValue, true);
        backgroundResource = typedValue.resourceId;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        @Bind(R.id.done_indicator)
        CheckBox doneIndicator;

        @Bind(R.id.title)
        TextView title;

        View view;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
            view = itemView;
        }
    }

    public void addModel(T model){
        int key = model.getId().intValue();
        int index = modelSparseArray.indexOfKey(key);
        modelSparseArray.append(key, model);
        if(key < 0)
            notifyItemInserted(modelSparseArray.size());
        else
            notifyItemChanged(index);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.row_layout, parent, false);
        view.setBackgroundResource(backgroundResource);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final T model = modelSparseArray.valueAt(position);
        holder.title.setText(model.getTitle());
        holder.doneIndicator.setChecked(model.isDone());
        holder.doneIndicator.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                model.setDone(isChecked);
                model.save();
            }
        });
    }



    @Override
    public int getItemCount() {
        return modelSparseArray.size();
    }
}

This question is almost exactly the same as I'm asking, however, the OP of that question gave the answer to the question using a pastebin which, unfortunately, the link is not working anymore.

The error is:

Error:(24, 1) error: BaseAdapter is not abstract and does not override abstract method onBindViewHolder(BaseAdapter.ViewHolder,int) in Adapter
Error:(80, 5) error: method does not override or implement a method from a supertype

The first error is pointing at the start of the class declaration, the second error points at the Override above onBindViewHolder

So I discovered the answer as soon as I posted the question, I'll post this in case anyone need the answer:

Change the RecyclerView.Adapter<BaseAdapter.ViewHolder> to RecyclerView.Adapter<BaseAdapter<T>.ViewHolder>

I originally created the base adapter without the type parameter so it worked with RecyclerView.Adapter<BaseAdapter.ViewHolder> , but after adding the type parameter, I also need to add <T> .

Another solution is making the internal ViewHolder static as @chRyNaN suggested.

Have you tried to change the method signature from

public void onBindViewHolder(ViewHolder holder, final int position)

to

public void onBindViewHolder(ViewHolder holder, int position)

Just make the second parameter NOT final .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM