Tiberal
Tiberal

Reputation: 420

RecyclerView.Adapter does not see overridden onBindViewHolder method?

I use DataBindings and RecyclerView in my project. I have a base adapter for RecyclerView. It looks like this

public abstract class BaseAdapter<T extends ViewDataBinding> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {

    public BaseAdapter() {}

    public class ViewHolder extends RecyclerView.ViewHolder {

        public T binding;

        public ViewHolder(View view) {
            super(view);
            binding = DataBindingUtil.bind(view);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        ... code ...
        }

}

ViewHolder extended classes differs only binding field type. After the implementation of the extended BaseAdapter class:

public class BaseAdapterExtended extends BaseAdapter<BaseAdapterExtendedBinding> {

    public BaseAdapterExtended(ArrayList<ItemModel> itemModels) {
        super();
        mData = itemModels;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        return new ViewHolder(BaseAdapterExtendedBinding.inflate(inflater, parent, false).getRoot());
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
    }

    @Override
    protected View getItemRootView(ViewHolder holder) {
        return holder.binding.item;
    }

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

i am got next compilation error:

error: BaseAdapterExtended is not abstract and does not override abstract method onBindViewHolder(BaseAdapter.ViewHolder,int) in Adapter

Seems like BaseAdapterExtended hasn't this method, but he exists. If I change

public void onBindViewHolder(ViewHolder holder, int position)

to

public void onBindViewHolder(BaseAdapter.ViewHolder holder, int position)

Projections compiled fine, but type binding will be ViewDataBinding instead BaseAdapterExtendedBinding. Why is this happening? Any ideas?

Upvotes: 11

Views: 9468

Answers (4)

mpellegr
mpellegr

Reputation: 3182

I just found out the reason to this weird issue. This is happening in my project too but only for adapters that are parametrized, like yours is. All other adapters saw the BindViewHolder() method without needing to explicitly specify the ViewHolder in the class. The solution is to parametrize the ViewHolder class with any random param type, this looks like it's a bug.

public abstract class BaseAdapter<T extends ViewDataBinding> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {

public BaseAdapter() {}

public class ViewHolder<RandomTypeNotUsed> extends RecyclerView.ViewHolder {

    public T binding;

    public ViewHolder(View view) {
        super(view);
        binding = DataBindingUtil.bind(view);
    }
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    ... code ...
    }

}

Upvotes: 2

user1978019
user1978019

Reputation: 3346

In my case I had forgotten to parameterize my superclass. When creating the class I hadn't yet created the ViewHolder, and it was very permissive except for the error on that method. I.e.:

public class FooAdapter extends RecyclerView.Adapter {

Had to be changed to

public class FooAdapter extends RecyclerView.Adapter<FooAdapter.FooViewHolder> {

This needed to be done anyways, but the only compiler error I got was in onBindViewHolder.

Upvotes: 27

Shayan_Aryan
Shayan_Aryan

Reputation: 2042

in this line:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    super.onBindViewHolder(holder, position);
}

replace ViewHolder with BaseAdapterExtended.ViewHolder

Upvotes: 7

Anubhav Sahu
Anubhav Sahu

Reputation: 71

Works fine for me! //like is my imageview

@Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int i) {
        MyViewHolder myViewHolder1 = (MyViewHolder)viewHolder;
        myViewHolder1.like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "yay" + i, Toast.LENGTH_SHORT ).show();
            }
        });
    }

Upvotes: 1

Related Questions