Incompatible types: cannot cast viewholder to imageviewholder

Moudiz picture Moudiz · Jan 30, 2016 · Viewed 7.8k times · Source

I am following a RecyclerView example and I have this error

incompatible types: cannot cast viewholder to imageviewholder

on this code

case TYPE_IMAGE:
            ImageViewHolder imageViewHolder = (ImageViewHolder) holder;

this is my full code(edited)

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private ArrayList<String> mDataset;

    public class ImageViewHolder extends RecyclerView.ViewHolder {
        //ImageView mImage;
        public TextView txtHeader;
        public TextView txtFooter;
        public ImageViewHolder(View itemView) {
            super (itemView);
            txtHeader = (TextView) itemView.findViewById(R.id.firstLine1);
            txtFooter = (TextView) itemView.findViewById(R.id.secondLine1);
        }
    }

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class TextViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView txtHeader;
        public TextView txtFooter;

        public TextViewHolder(View v) {
            super(v);
            txtHeader = (TextView) v.findViewById(R.id.firstLine);
            txtFooter = (TextView) v.findViewById(R.id.secondLine);
        }
    }

    public void add(int position, String item) {
        mDataset.add(position, item);
        notifyItemInserted(position);
    }

    public void remove(String item) {
        int position = mDataset.indexOf(item);
        mDataset.remove(position);
        notifyItemRemoved(position);
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(ArrayList<String> myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
        // set the view's size, margins, paddings and layout parameters
        TextViewHolder vh = new TextViewHolder(v);
        return vh;
    }

    private static final int TYPE_IMAGE = 1;
    private static final int TYPE_GROUP = 2;

    @Override
    public int getItemViewType(int position) {
        // here your custom logic to choose the view type
        return position == 0 ? TYPE_IMAGE : TYPE_GROUP;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder TextViewHolder, int position) {

        switch (TextViewHolder.getItemViewType()) {

            case TYPE_IMAGE:
                ImageViewHolder imageViewHolder = (ImageViewHolder) TextViewHolder;
               // imageViewHolder.mImage.setImageResource(...);
                final String namev = mDataset.get(position);
                imageViewHolder.txtHeader.setText(mDataset.get(position));
                imageViewHolder.txtHeader.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        remove(namev);
                    }
                });

                break;

            case TYPE_GROUP:
                TextViewHolder viewHolder = (TextViewHolder) TextViewHolder;
              //  viewHolder.txtHeader.setText(...)
                final String name = mDataset.get(position);
                viewHolder.txtHeader.setText(mDataset.get(position));
                viewHolder.txtHeader.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        remove(name);
                    }
                });

                viewHolder.txtFooter.setText("Footer: " + mDataset.get(position));

                break;
        }
/*
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        final String name = mDataset.get(position);
        holder.txtHeader.setText(mDataset.get(position));
        holder.txtHeader.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                remove(name);
            }
        });

        holder.txtFooter.setText("Footer: " + mDataset.get(position));
*/
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.size();
    }

}

error here

@Override
public RecyclerView.ViewHolder  onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    switch (viewType) {

        case TYPE_IMAGE: {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
            // return new ImageViewHolder(itemView);
            ImageViewHolder vh = new ImageViewHolder(itemView);
            return vh;
        }
        case TYPE_GROUP: {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
            // return new TextViewHolder(itemView);
            TextViewHolder vh = new TextViewHolder(itemView);
            return vh;
        }
    }
}// error here missing return statement

Answer

JpCrow picture JpCrow · Jan 30, 2016

You should change:

 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.TextViewHolder> 

for:

 public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 

And then change your onCreateViewHolder in order to accept multiple ViewTypes:

    @Override
    public MyAdapter.TextViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType)

for:

   @Override
   public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType)

And then change the onBindViewHolder method:

 @Override
 public void onBindViewHolder(TextViewHolder TextViewHolder, int position) 

for:

 @Override
 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)

And don´t forget to set your ViewHolder types:

   @Override
   public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType){
    switch (viewType) {

       case TYPE_IMAGE: {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.XXX, parent, false);
            return new ImageViewHolder(itemView);
            }
       case TYPE_GROUP: {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.XXX, parent, false);
            return new TextViewHolder(itemView);
           }
      }