RecyclerView的onBindViewHolder中的ClassCastException

时间:2016-03-01 20:22:12

标签: android android-recyclerview

我想在回收站视图中显示不同的项目/布局。所以这就是我定义这些项目的方式:

public class SearchItem {

    public static final int TYPE_DEFAULT = 0;
    public static final int TYPE_LOADING = 1;

    public int type;

    public SearchItem(int type) {
        this.type = type;
    }

    public static class DefaultItem extends SearchItem {

        public String title;

        public DefaultItem(String title) {
            super(TYPE_DEFAULT);
            this.title = title;
        }
    }

    public static class LoadingItem extends SearchItem {

        public String icon, title;

        public LoadingItem(String icon, String title) {
            super(TYPE_LOADING);
            this.icon = icon;
            this.title = title;
        }
    }
}

所以基本上我有两种类型。在适配器中,将为每个项目选择适当的布局:

public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>{

    public ArrayList<SearchItem> items = new ArrayList<>();

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

    @Override
    public int getItemViewType(int position) {
        return items.get(position).type;
    }


    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        LayoutInflater mInflater = LayoutInflater.from(parent.getContext());

        switch (viewType) {
            case SearchItem.TYPE_LOADING:
                ViewGroup vLoading = (ViewGroup) mInflater.inflate(R.layout.search_item_loading, parent, false);
                return new LoadingViewHolder(vLoading);
            case SearchItem.TYPE_DEFAULT:default:
                ViewGroup vDefault = (ViewGroup) mInflater.inflate(R.layout.search_item_default, parent, false);
                return new DefaultViewHolder(vDefault);
        }
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {

        SearchItem item = items.get(position);

        switch (holder.getItemViewType()) {
            case SearchItem.TYPE_DEFAULT:
                DefaultViewHolder defaultViewHolder = (DefaultViewHolder) holder;
                defaultViewHolder.mTextViewTitle.setText(((SearchItem.DefaultItem)item).title);
            case SearchItem.TYPE_LOADING:
                LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
                loadingViewHolder.mTextViewIcon.setText(((SearchItem.LoadingItem)item).icon);
                loadingViewHolder.mTextViewTitle.setText(((SearchItem.LoadingItem)item).title);
        }
    }

    /**
     * Base view holder.
     */
    public static class BaseViewHolder extends RecyclerView.ViewHolder {
        public BaseViewHolder(View view) {
            super(view);
        }
    }

    public static class DefaultViewHolder extends BaseViewHolder {

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

        public DefaultViewHolder(View mView) {
            super(mView);
            ButterKnife.bind(this, mView);
        }
    }

    public static class LoadingViewHolder extends BaseViewHolder {

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

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

        public LoadingViewHolder(View mView) {
            super(mView);
            ButterKnife.bind(this, mView);
        }
    }
}

onBindViewHolder

LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;

android studio已经向我发出警告,告诉我在holder转换为LoadingViewHolder时可能会遇到异常。运行项目时,我得到:

SearchAdapter$DefaultViewHolder cannot be cast to SearchAdapter$LoadingViewHolder

所以不知何故DefaultViewHolder被转换为LoadingViewHolder但它不应该。而是应该铸造BaseViewHolder。你看错了吗?

2 个答案:

答案 0 :(得分:1)

根据您的要求以及您要实现的目标,您编写的代码是错误的。正如我可以看到您正在扩展的实现,而不是Generic RecyclerView Holder,即它将基本视图持有者作为单个持有者

extends RecyclerView.Adapter<RecyclerView.ViewHolder>

而不是

extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>

这里整个代码如何做到

https://gist.github.com/umesh0492/e65d5195d8962b1a3049

答案 1 :(得分:0)

可能会迟到但是对于那些得到同样错误的人来说。 使用&#34; break&#34;在每种情况下,你都不会得到任何错误。