【问题标题】:RecyclerView GridLayoutManager with multiple view type, Viewholder cast Exception具有多种视图类型的 RecyclerView GridLayoutManager,Viewholder cast Exception
【发布时间】:2015-07-29 10:43:37
【问题描述】:

所以我正在关注这个tutorial,我有一个 RecyclerViewGridLayoutManager 实现。GridLayoutManager 有 2 列。我想要两种视图类型,所以我使用了两个 ViewHolders 扩展了 RecyclerView.ViewHolder 并且我覆盖了这个方法:getItemViewType(int position),但我接受了 Cast Exception。 Logcat 显示如下:

java.lang.ClassCastException:adapter.AdapterListItemHome$CommentViewHolder0 无法转换为 adapter.AdapterListItemHome$CommentViewHolder1 在 adapter.AdapterListItemHome.onBindViewHolder(AdapterListItemHome.java:200) 在 adapter.AdapterListItemHome.onBindViewHolder(AdapterListItemHome.java:25)

但我不会将 CommentViewHolder0 与 CommentViewHolder1 一起使用,例如 Line 问题是这样的:

final CommentViewHolder0 vh0 = (CommentViewHolder0)cvh;

这是来自适配器 (AdapterListItemHome.java) 的代码:

public class AdapterListItemHome extends RecyclerView.Adapter<RecyclerView.ViewHolder>  {
ArrayList<GadgetItem> mListItem;
Context mContext;
private int choice;
public static OnItemClickListener listener;// Define listener member variable
public static final int FIRST_ITEM = 0;
public static final int REST_ITEMS = 1;
/**
 * Defines the listener interface
 */
public interface OnItemClickListener {
    void onItemClick(View itemView, int position);
}
// Define the method that allows the parent activity or fragment to define the listener
public void setOnItemClickListener(OnItemClickListener listener) {
    this.listener = listener;
}

/**
 * view holder - holds the widgets - classical
 */
public class CommentViewHolder1 extends RecyclerView.ViewHolder {
    public ProgressBar pgLoading;
    public TextView tv_title;
    public ImageView imgView;

    //constructor
    public CommentViewHolder1(final View itemView) {
        super(itemView);
        // Find the TextView in the LinearLayout
        tv_title = ((TextView) itemView.findViewById(R.id.namgeItem));
        pgLoading = (ProgressBar) itemView.findViewById(R.id.pbLoadingImage);
        imgView = (ImageView) itemView.findViewById(R.id.imgItem);
        itemView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                // Triggers click upwards to the adapter on click
                if (listener != null)
                    listener.onItemClick(itemView, getPosition());
            }
        });
    }
}
/**
 * second viewHolder
 */
public class CommentViewHolder0 extends RecyclerView.ViewHolder {

    public ProgressBar pgLoading;
    public TextView tv_title;
    public ResizableImageView imgView;
    public TextView tv_date;

    //constructor
    public CommentViewHolder0(final View itemView) {
        super(itemView);
        // Find the TextView in the LinearLayout
        tv_title = ((TextView) itemView.findViewById(R.id.namgeItem));
        tv_date = ((TextView) itemView.findViewById(R.id.tv_date));
        pgLoading = (ProgressBar) itemView.findViewById(R.id.pbLoadingImage);
        imgView = (ResizableImageView) itemView.findViewById(R.id.resizable_image);
        imgView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                // Triggers click upwards to the adapter on click
                if (listener != null)
                    listener.onItemClick(imgView, getPosition());

            }
        });
    }

}
/*
 * VF: Constructor
 */
public AdapterListItemHome(Context pContext, ArrayList<GadgetItem> pListGadget) {
    this.mContext = pContext;
    this.mListItem = pListGadget;
}

/**
 * Replace the contents of a view (invoked by the layout manager)
 * @param viewGroup
 * @param ViewType
 * @return
 */

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int ViewType){
    View v;
    //Log.d("bill", "viewtype = " + String.valueOf(ViewType));
    switch(ViewType){
        case REST_ITEMS:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item, viewGroup, false);
            CommentViewHolder1 cvh1 = new CommentViewHolder1(v);
            return cvh1;
        case FIRST_ITEM:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item_home, viewGroup, false);
            CommentViewHolder0 cvh0 = new CommentViewHolder0(v);
            return cvh0;
        default:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item, viewGroup, false);
            CommentViewHolder1 cvh2 = new CommentViewHolder1(v);
            return cvh2;
    }
}

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

    Transformation transformation;
    GadgetItem item;

    switch ( cvh.getItemViewType () ){

        case REST_ITEMS:

            final CommentViewHolder1 vh1 = (CommentViewHolder1)cvh;
            item = mListItem.get(position);
            vh1.tv_title.setText(item.gadget_title);
            vh1.pgLoading.setVisibility(View.VISIBLE);
            vh1.imgView.setImageDrawable(null);
            /**
             * clicking on the image view
             */
             transformation = new Transformation() {

                @Override
                public Bitmap transform(Bitmap source) {
                    int targetWidth = vh1.imgView.getWidth();
                    double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                    int targetHeight = (int) (targetWidth * aspectRatio);
                    // Bitmap result = Bitmap.createScaledBitmap(source,
                    // targetWidth,
                    // targetHeight, false);
                    Bitmap result = scaleAndCropImage(source, 300);
                    if (result != source) {
                        // Same bitmap is returned if sizes are the same
                        source.recycle();
                    }
                    return result;
                }

                @Override
                public String key() {
                    return "transformation" + " desiredWidth";
                }
            };
            Picasso.with(mContext).load(item.gadget_image).into(vh1.imgView, new Callback() {
                @Override
                public void onError() {
                }

                @Override
                public void onSuccess() {
                    vh1.pgLoading.setVisibility(View.GONE);
                }

            });

        case FIRST_ITEM:

            final CommentViewHolder0 vh0 = (CommentViewHolder0)cvh;
            item = mListItem.get(position);
            vh0.tv_title.setText(item.gadget_title);
            vh0.pgLoading.setVisibility(View.VISIBLE);
            vh0.imgView.setImageDrawable(null);
            vh0.tv_date.setText(item.gadget_pubDate);
            /**
             * clicking on the image view
             */
             transformation = new Transformation() {

                @Override
                public Bitmap transform(Bitmap source) {
                    int targetWidth = vh0.imgView.getWidth();
                    double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                    int targetHeight = (int) (targetWidth * aspectRatio);
                    // Bitmap result = Bitmap.createScaledBitmap(source,
                    // targetWidth,
                    // targetHeight, false);
                    Bitmap result = scaleAndCropImage(source, 300);
                    if (result != source) {
                        // Same bitmap is returned if sizes are the same
                        source.recycle();
                    }
                    return result;
                }

                @Override
                public String key() {
                    return "transformation" + " desiredWidth";
                }
            };
            Picasso.with(mContext).load(item.gadget_image).into(vh0.imgView, new Callback() {
                @Override
                public void onError() {

                }

                @Override
                public void onSuccess() {
                    vh0.pgLoading.setVisibility(View.GONE);
                }

            });
    }
}
// Return the size of  dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mListItem.size();
}
/*  (non-Javadoc)
 *  VF: creating a item to show
 */

Bitmap scaleAndCropImage(Bitmap image, int height) {
    float ratio = (float) (height) / (float) image.getHeight();
    int width = (int) ((float) image.getWidth() * ratio);
    return ScalingUtilities.createScaledBitmap(image, width, height, ScalingUtilities.ScalingLogic.CROP);
}

@Override
public int getItemViewType(int position) {
    int viewType;

        if (position == 1)
            viewType = FIRST_ITEM;
        else
            viewType = REST_ITEMS;


    return viewType;
    }
 }

这就是 RecyclerView 正在实施的 Fragment

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent , Bundle savedInstanceState) {
    if(parent == null)
        return null;
    if(v != null)
        return v;
    //initialize the view v
    v = inflater.inflate(R.layout.fragment_list_item_home, parent , false);
    //initialization Recycler view
    mRecyclerView = (RecyclerView) v.findViewById(R.id.listItem_home);
    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new GridLayoutManager(getActivity(),2);
    mRecyclerView.addItemDecoration(new DividerItemDecoration(4,2));
    mRecyclerView.getItemAnimator().setMoveDuration(5000);
    mRecyclerView.setLayoutManager(mLayoutManager);
    if(mAdapter == null) {
                //setting the adapter
                mAdapter = new AdapterListItemHome(getActivity(),mList);
                mRecyclerView.setAdapter(mAdapter);

                v.setFocusableInTouchMode(true); //focusing when touching
                v.requestFocus(); //To force focus to a specific view
                mAdapter.setOnItemClickListener(new AdapterListItemHome.OnItemClickListener() {

                    @Override
                    public void onItemClick(View view, int position) {
                        onListViewItemClick(position);
                    }
                });
            }

我一直在到处寻找,实现的方法都是一样的,我不知道问题出在哪里。感谢您的帮助

【问题讨论】:

  • 你找出问题所在了吗?我在我们的一个项目中遇到了同样的问题。具有讽刺意味的是,我几乎遵循了几周前在另一个项目中首次实施的相同实施,在其中我没有遇到任何问题。
  • @Andrew 是的,我解决了这个问题,我会在下面发布答案
  • 也解决了我的问题。显然,我使用的是 onCreateViewHolder(ViewGroup viewGroup, int position),其中 position 作为第二个参数,而不是 viewType。不知道它在另一个应用程序上的运行情况如何。

标签: android classcastexception android-viewholder android-recyclerview


【解决方案1】:

这段代码对我来说很好用:

public class AdapterListItemHome extends RecyclerView.Adapter<AdapterListItemHome.MainHolder>  {
ArrayList<GadgetItem> mListItem;
Context mContext;
public static OnItemClickListener listener;// Define listener member variable
public static final int FIRST_ITEM = 0;
public static final int REST_ITEMS = 1;
/**
 * Defines the listener interface
 */
public interface OnItemClickListener {
    void onItemClick(View itemView, int position);
}
// Define the method that allows the parent activity or fragment to define the listener
public void setOnItemClickListener(OnItemClickListener listener) {
    this.listener = listener;
}
public class MainHolder extends RecyclerView.ViewHolder {

    public MainHolder(View itemView){
        super(itemView);
    }
}
/**
 * view holder - holds the widgets 
 */
public class CommentViewHolder1 extends MainHolder {
    public ProgressBar pgLoading;
    public TextView tv_title;
    public ImageView imgView;

    //constructor
    public CommentViewHolder1(final View itemView) {
        super(itemView);
        // Find the TextView in the LinearLayout
        tv_title = ((TextView) itemView.findViewById(R.id.namgeItem));
        pgLoading = (ProgressBar) itemView.findViewById(R.id.pbLoadingImage);
        imgView = (ImageView) itemView.findViewById(R.id.imgItem);
        itemView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                // Triggers click upwards to the adapter on click
                if (listener != null)
                    listener.onItemClick(itemView, getPosition());
            }
        });
    }   
}
/**
 * second viewHolder
 */
public class CommentViewHolder0 extends MainHolder {

    public ProgressBar pgLoading;
    public TextView tv_title;
    public ResizableImageView imgView;
    public TextView tv_date;

    //constructor
    public CommentViewHolder0(final View itemView) {
        super(itemView);
        // Find the TextView in the LinearLayout
        tv_title = ((TextView) itemView.findViewById(R.id.namgeItem_home));
        tv_date = ((TextView) itemView.findViewById(R.id.tv_date));
        pgLoading = (ProgressBar) itemView.findViewById(R.id.pbLoadingImage_home);
        imgView = (ResizableImageView) itemView.findViewById(R.id.resizable_image);
        imgView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                // Triggers click upwards to the adapter on click
                if (listener != null)
                    listener.onItemClick(imgView, getPosition());

            }
        });
    }

}
public AdapterListItemHome(Context pContext, ArrayList<GadgetItem> pListGadget,ArrayList<String> pDateList) {
    this.mContext = pContext;
    this.mListItem = pListGadget;
    this.mDateList = pDateList;
    p = new Picasso.Builder(mContext)
            .memoryCache(new LruCache(cacheSize))
            .build();
}

/**
 * Replace the contents of a view (invoked by the layout manager)
 */
@Override
public MainHolder onCreateViewHolder(ViewGroup viewGroup, int ViewType){
    View v
    switch(ViewType){
        case REST_ITEMS:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item, viewGroup, false);
            CommentViewHolder1 cvh1 = new CommentViewHolder1(v);
            return cvh1;
        case FIRST_ITEM:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item_home, viewGroup, false);
            CommentViewHolder0 cvh0 = new CommentViewHolder0(v);
            return cvh0;
        default:
            v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item, viewGroup, false);
            CommentViewHolder1 cvh2 = new CommentViewHolder1(v);
            return cvh2;
    }
}

@Override
public void onBindViewHolder(MainHolder cvh, int position) {

    switch ( cvh.getItemViewType () ){

        case REST_ITEMS:

            final CommentViewHolder1 vh1 = (CommentViewHolder1)cvh;
            GadgetItem item1 = mListItem.get(position);
            vh1.tv_title.setText(fixTitleText(20, item1.gadget_title) + item1.gadget_price);
            vh1.pgLoading.setVisibility(View.VISIBLE);
            vh1.imgView.setImageDrawable(null);
            final int y = 200;
            final int x = 200;
            //picasso
            p.with(mContext).load(item1.gadget_image).resize(x, y).centerCrop().into(vh1.imgView, new Callback() {
                @Override
                public void onError() {
                }

                @Override
                public void onSuccess() {
                    vh1.pgLoading.setVisibility(View.GONE);
                }

            });
            break;
        case FIRST_ITEM:
            final CommentViewHolder0 vh0 = (CommentViewHolder0)cvh;
            GadgetItem item = mListItem.get(position);
            vh0.tv_title.setText(fixTitleText(63, item.gadget_title) + item.gadget_price);
            vh0.pgLoading.setVisibility(View.VISIBLE);
            vh0.imgView.setImageDrawable(null);
            String dateTime = fixdateTime(item.gadget_pubDate);
            String date = null;
            try {
                date = calculateDate(dateTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            vh0.tv_date.setText(date + " " + dateTime);

            final int y1 = 335;
            final int x1 = 400;
            //picasso
            p.with(mContext).
                    load(item.gadget_image).resize(x1, y1).centerCrop().into(vh0.imgView, new Callback() {
                @Override
                public void onError() {

                }

                @Override
                public void onSuccess() {
                    vh0.pgLoading.setVisibility(View.GONE);
                }

            });

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

    return mListItem.size();
}
/*  (non-Javadoc)
 *  VF: creating a item to show
 */
@Override
public int getItemViewType(int position) {
    int viewType;

        if (position == 0 || (!(mDateList.get(position).equals(mDateList.get(position -1 )))))
            viewType = FIRST_ITEM;
        else
            viewType = REST_ITEMS;

    return viewType;
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多