BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习BaseViewHolder扩展功能的实现代码学习(四)
2017-03-14 00:00
906 查看
摘要:BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习BaseViewHolder扩展功能的实现代码学习(四)
version:2.8.5
更多分享请看:http://cherylgood.cn
今天我们来分析下BaseQuickAdapter是如何实现BaseViewHolder的可扩展性的。
看代码
publicabstractclassBaseQuickAdapter<T,KextendsBaseViewHolder>extendsRecyclerView.Adapter<K>{
从类的定义我们可以看到两个范型类型T、K,T是我们的数据源的类型,K就是我们的viewHolder了,你可以使用已提供好的BaseViewHolder,也可以通过继承BaseViewHolder来进行扩展。
接下来我们分析的入口点就是代码中是如何创建ViewHolder的。ViewHolder的创建是在onCreateViewHolder生命回调方法中调用的,我们来看源码:
@Override
publicKonCreateViewHolder(ViewGroupparent,intviewType){
Log.d(TAG,"#testonCreateViewHolder");
KbaseViewHolder=null;
this.mContext=parent.getContext();
this.mLayoutInflater=LayoutInflater.from(mContext);
switch(viewType){
caseLOADING_VIEW:
baseViewHolder=getLoadingView(parent);
break;
caseHEADER_VIEW:
baseViewHolder=createBaseViewHolder(mHeaderLayout);
break;
caseEMPTY_VIEW:
baseViewHolder=createBaseViewHolder(mEmptyLayout);
break;
caseFOOTER_VIEW:
baseViewHolder=createBaseViewHolder(mFooterLayout);
break;
default:
baseViewHolder=onCreateDefViewHolder(parent,viewType);
}
returnbaseViewHolder;
}
里面每个case语句里的代码最终都会调用同一个方法:
/**
*ifyouwanttousesubclassofBaseViewHolderintheadapter,
*youmustoverridethemethodtocreatenewViewHolder.
*
*@paramviewview
*@returnnewViewHolder
*/
protectedKcreateBaseViewHolder(Viewview){
Classtemp=getClass();
Classz=null;
/**
*检测当前类及其父类是否与BaseViewHolder相同或者具备相同接口如果具备,如果没有z==null
*/
while(z==null&&null!=temp){
z=getInstancedGenericKClass(temp);
temp=temp.getSuperclass();
}
Kk=createGenericKInstance(z,view);
returnnull!=k?k:(K)newBaseViewHolder(view);
}
里面主要是用了java的反射技术实现的。我们可以看到temp这个字段:
temp表示当前的实际类型;
可以看到里面调用了这么一句代码z=getInstancedGenericKClass(temp);
方法的代码如下,部分注释是我加上去的。
/**
*getgenericparameterK
*
*@paramz
*@return
*/
privateClassgetInstancedGenericKClass(Classz){
/**
*ReturnstheTyperepresentingthedirectsuperclassoftheentity
*(class,inte
7fe0
rface,primitivetypeorvoid)representedbythisClass.
*/
Typetype=z.getGenericSuperclass();
/**
*ParameterizedTyperepresentsaparameterizedtypesuchasCollection<String>.
*/
if(typeinstanceofParameterizedType){
/**
*getActualTypeArguments()
*
*ReturnsanarrayofTypeobjectsrepresentingtheactual
*typeargumentstothistype.
*/
Type[]types=((ParameterizedType)type).getActualTypeArguments();
for(Typetemp:types){
if(tempinstanceofClass){
ClasstempClass=(Class)temp;
//判断tempClass是否是BaseViewHolder类型相同或具有相同的接口
if(BaseViewHolder.class.isAssignableFrom(tempClass)){
returntempClass;
}
}
}
}
returnnull;
}
里面的Typetype=z.getGenericSuperclass();返回z的父类类型,包括实现的接口类型等。所以z是个集合。
我们对其进行遍历:
Type[]types=((ParameterizedType)type).getActualTypeArguments();
for(Typetemp:types){
if(tempinstanceofClass){
ClasstempClass=(Class)temp;
//判断tempClass是否是BaseViewHolder类型相同或具有相同的接口
if(BaseViewHolder.class.isAssignableFrom(tempClass)){
returntempClass;
}
}
}
首先判断其是否是一个类类型:tempinstanceofClass
如果是,判断是否是BaseViewHolder类型相同或具有相同的接口,是的话返回,不是返回null:
if(BaseViewHolder.class.isAssignableFrom(tempClass)){
returntempClass;
}
所以protectedKcreateBaseViewHolder(Viewview)方法中的while循环的作用就是
不断遍历当前类的父类。判断其父类是否是BaseViewHolder的子类,代码如下:
while(z==null&&null!=temp){
z=getInstancedGenericKClass(temp);
temp=temp.getSuperclass();
}
最终z里面存储的是我们的BaseViewHolder类字节码或者是继承自BaseViewHolder的类的字节码;
拿到类的字节码后我们就要实例化它了:
实例化时我们调用的是Kk=createGenericKInstance(z,view);
代码如下:
/**
*trytocreateGenericKinstance
*
*@paramz
*@paramview
*@return
*/
privateKcreateGenericKInstance(Classz,Viewview){
try{
Constructorconstructor;
Stringbuffer=Modifier.toString(z.getModifiers());
StringclassName=z.getName();
//innerandunstaticclass
if(className.contains("$")&&!buffer.contains("static")){
constructor=z.getDeclaredConstructor(getClass(),View.class);
return(K)constructor.newInstance(this,view);
}else{
constructor=z.getDeclaredConstructor(View.class);
return(K)constructor.newInstance(view);
}
}catch(NoSuchMethodExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(InvocationTargetExceptione){
e.printStackTrace();
}
returnnull;
}
里面主要做了两个操作:1、我们的类是否是内部类且非晶态内部类,是,按内部类的实例化步骤处理,2、按正常类型进行处理。
1、先获取className,如果是内部类。类名会包含有$符号且不包含static
最终如果实例化成功会返回实例化的对象,否则返回null
所以最终我们最后的代码是一个三目运算符,
returnnull!=k?k:(K)newBaseViewHolder(view);
如果前面实例化返回null,我们会默认返回一个
newBaseViewHolder(view);
version:2.8.5
更多分享请看:
今天我们来分析下BaseQuickAdapter是如何实现BaseViewHolder的可扩展性的。
看代码
从类的定义我们可以看到两个范型类型T、K,T是我们的数据源的类型,K就是我们的viewHolder了,你可以使用已提供好的BaseViewHolder,也可以通过继承BaseViewHolder来进行扩展。
接下来我们分析的入口点就是代码中是如何创建ViewHolder的。ViewHolder的创建是在onCreateViewHolder生命回调方法中调用的,我们来看源码:
里面每个case语句里的代码最终都会调用同一个方法:
里面主要是用了java的反射技术实现的。我们可以看到temp这个字段:
temp表示当前的实际类型;
可以看到里面调用了这么一句代码z=getInstancedGenericKClass(temp);
方法的代码如下,部分注释是我加上去的。
相关文章推荐
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习BaseViewHolder扩展功能的实现代码学习(四)
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习上拉加载的实现代码(三)
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习上拉加载的实现代码(三)
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习之预加载的实现(二)
- BaseRecyclerViewAdapterHelper开源项目之BaseMultiItemQuickAdapter 实现多类型源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseSectionQuickAdapter 实现分组效果的源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseSectionQuickAdapter 实现Expandable And collapse效果的源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseSectionQuickAdapter 实现分组效果的源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseMultiItemQuickAdapter 实现多类型源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseSectionQuickAdapter 实现Expandable And collapse效果的源码学习
- BaseRecyclerViewAdapterHelper开源项目之点击事件源码学习
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习.
- BaseRecyclerViewAdapterHelper开源项目之点击事件源码学习
- RecyclerView分组之BaseRecyclerViewAdapterHelper(实现分组功能)
- Android开源之BaseRecyclerViewAdapterHelper(持续更新!)
- BaseRecyclerViewAdapterHelper 实现不同条目的列表
- 配合BaseRecyclerViewAdapterHelper,实现悬浮吸顶
- Android开源之BaseRecyclerViewAdapterHelper(持续更新!)
- Android 开源框架BaseRecyclerViewAdapterHelper使用——RecyclerView万能适配器
- Android开源之BaseRecyclerViewAdapterHelper(持续更新!)