Skip to content

MultipleItemRvAdapter 自定义BaseViewHolder出现强转异常的问题 #9

Open

Description

@K-Hector

异常信息:
java.lang.ClassCastException: com.chad.library.adapter.base.BaseViewHolder cannot be cast to adapter.itemprovider.SmallContentViewHolder
at adapter.itemprovider.IPCommercialDetailSmallContent.convert(IPCommercialDetailSmallContent.java:21)
at com.chad.library.adapter.base.MultipleItemRvAdapter.convert(MultipleItemRvAdapter.java:70)
at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:951)
at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:68)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6476)

这是其中一种类型的
image

这是另一种类型的:
image

适配器代码类型指定为了BaseViewHolder:
image

断点后异常出现的位置是在MultipleItemRvAdapter中的convert()方法中:
image

感觉这样强转一定会出错的吧?

Activity

  1. K-Hector commented on Jul 10, 2018

    @K-Hector
    Author

    问题解决了,重写onCreateDefViewHolder(ViewGroup parent, int viewType)方法,,反射用的字节码对象应该拿BaseItemProvider上的

    @Override
    protected V onCreateDefViewHolder(ViewGroup parent, int viewType) {
        int layoutId = mLayoutResId;
        if (getMultiTypeDelegate() != null) {
            layoutId = getMultiTypeDelegate().getLayoutId(viewType);
        }
        View view = getItemView(layoutId, parent);
    
        Class temp = mItemProviders.get(viewType).getClass();
        Class z = null;
        while (z == null && null != temp) {
            z = getInstancedGenericKClass(temp);
            temp = temp.getSuperclass();
        }
        V k;
        // 泛型擦除会导致z为null
        if (z == null) {
            k = (V) new BaseViewHolder(view);
        } else {
            k = createGenericKInstance(z, view);
        }
        return k != null ? k : (V) new BaseViewHolder(view);
    }
    
    protected Class getInstancedGenericKClass(Class z) {
        Type type = z.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            for (Type temp : types) {
                if (temp instanceof Class) {
                    Class tempClass = (Class) temp;
                    if (BaseViewHolder.class.isAssignableFrom(tempClass)) {
                        return tempClass;
                    }
                } else if (temp instanceof ParameterizedType) {
                    Type rawType = ((ParameterizedType) temp).getRawType();
                    if (rawType instanceof Class && BaseViewHolder.class.isAssignableFrom((Class<?>) rawType)) {
                        return (Class<?>) rawType;
                    }
                }
            }
        }
        return null;
    }
    
    protected V createGenericKInstance(Class z, View view) {
        try {
            Constructor constructor;
            // inner and unstatic class
            if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) {
                constructor = z.getDeclaredConstructor(getClass(), View.class);
                constructor.setAccessible(true);
                return (V) constructor.newInstance(this, view);
            } else {
                constructor = z.getDeclaredConstructor(View.class);
                constructor.setAccessible(true);
                return (V) constructor.newInstance(view);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions