1,前言
Recycleview已经是我们经常使用的
数据的绑定和视图的创建关在Adapter适配器
基本使用
2,优化
先看最终版
1)我们接着看
val sourceImpl = SourceImpl(datas)
mRecyclerView.adapter = sourceImpl.adapter(AdapterAttentionBinding::class.java)
sourceImpl是一个对象实现了接口ISource.class
sourceImpl.adapter(AdapterAttentionBinding::class.java)?
adapter(...)?是一个基于ISource.class 扩展函数
而其中?TypeSupportAdaper.class 才算是我们 adapter 本体
?TypeSupportAdaper.class?继承至?ListSetAdapter.class 继承至?ListAbstacyAdapter.class
1)先看?ListAbstacyAdapter.class
2)再看ListSetAdapter.class
?
3)接着是重点TypeSupportAdaper.class
3)讲解
ListSetAdapter.class 我这里调用一个方法,默认绑定一个“bean”数据
是一个扩展方法
其本质就是默认反射dataBinding的? setBean(item)方法? 默认绑定数据
当然前提是layout文件也要写好配置
所以当你只是简单的展示数据,你只需要把你layout文件设置好Bean和xml绑定。然后默认这个adapter就自动绑定了一组数据
接着我们看核心类
TypeSupportAdaper.class
构造方法:
1,默认构造方法是
*需要一个数据集合
*需要一个类型(itemType)
2,第二个构造方法是默认只有一种类型 ZERO
核心函数:
fun <D : ViewDataBinding> plusAll(type: Int, clazz: Class<D>, viewCreate: (dataBinding: D, type: Int) -> Unit, convert: (dataBinding: D, item: ITEM, postion: Int) -> Unit): TypeSupportAdaper<ITEM>
?调用后返回本身可以继续调用此函数
存储所有itemType 基于type(key)类型
扩展函数反射创建DataBinding实例
还有两个默认都会执行的全局函数
函数重载与扩展函数:
最后我们写一个static函数
跟上面之前的扩展函数结合~
所以回到之前
一切水到渠成~
最后展示下不同情况的初始化
多种类型
Tip)使用ViewModel.class 实现ISource.class接口,就可以管理数据源了再结合? PageSupport.class分页快速高效率处理列表功能数据绑定
https://blog.csdn.net/qq_30523931/article/details/122414329https://blog.csdn.net/qq_30523931/article/details/122414329
/**
* 一个适配不同item type的适配器
* @param ITEM 数据类型
* @property cb HoldeGetItemType<ITEM>
* @constructor
*/
class TypeSupportAdaper<ITEM>(datas: List<ITEM>, private var typeBreakMethod: (Int) -> Int) : ListSetAdapter<ITEM>(datas) {
constructor(datas: List<ITEM>) : this(datas, { ZERO })
/**
* 所有viewtype的一个集合
*/
private val typeDataBindings = SparseArray<HolderDataBindingClass<ITEM, *>>()
/**
* 默认数据绑定执行的方法,不关乎那种类型
*/
var allConvertMethod: ((ViewDataBinding, ITEM, Int) -> Unit)? = null
/**
* 默认数据界面创建的方法,不关乎那种类型
*/
var allViewCreateMethod: ((ViewDataBinding, Int, ViewGroup) -> Unit)? = null
override fun getItemViewType(position: Int) = typeBreakMethod(position)
/**
* adapter 数据绑定回调
* @param d ViewDataBinding
* @param entity ITEM 数据
* @param postion Int 位置
*/
override fun convertData(d: ViewDataBinding, entity: ITEM, postion: Int) {
typeDataBindings[getItemViewType(postion)].holderConvert?.convertData(d, entity, postion)
allConvertMethod?.invoke(d, entity, postion)
}
/**
* adapter 数据界面创建回调
* @param parent ViewGroup 当前的recycleView
* @param viewType Int 类型
* @return DataBindingViewHolder
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder {
val hc = typeDataBindings[viewType]
val dataBinding: ViewDataBinding = dataBindingInflate(hc.hodlerDataBindingClass() as Class<ViewDataBinding>, parent) as ViewDataBinding
hc.holderViewCreate?.convertData(dataBinding, viewType)
allViewCreateMethod?.invoke(dataBinding, viewType, parent)
return DataBindingViewHolder(dataBinding.root, dataBinding)
}
/**
* 添加一个 [数据页面创建]时的回调基于databiding类型 默认使用 [ZORE]
* @param clazz Class<D>
* @param hc Function2<[@kotlin.ParameterName] D, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusViewCreate(clazz: Class<D>, hc: (dataBinding: D, type: Int) -> Unit) = plusViewCreate(ZERO, clazz, hc)
/**
* 添加一个 [数据页面创建]时的回调基于databiding类型 ,指定是哪个类型[ViewType]
* @param type Int
* @param clazz Class<D>
* @param hc Function2<[@kotlin.ParameterName] D, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusViewCreate(type: Int, clazz: Class<D>, hc: (dataBinding: D, type: Int) -> Unit): TypeSupportAdaper<ITEM> {
val hcDb = HolderDataBindingClass<ITEM, D>(type = type, clazz = clazz, null)
hcDb.adaper = this
hcDb.holderViewCreate = HolderViewCreate(hc)
typeDataBindings.put(hcDb.t, hcDb)
return this
}
/**
* 添加一个 [数据绑定]时的回调基于databiding类型 默认使用 [ZORE]
* @param clazz Class<D>
* @param convert Function3<D, ITEM, Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusConvert(clazz: Class<D>, convert: (D, ITEM, Int) -> Unit) = plusConvert(ZERO, clazz, convert)
/**
* 添加一个 [数据绑定] 时 的回调基于databiding类型 ,指定是哪个类型[ViewType]
* @param type Int
* @param clazz Class<D>
* @param convert Function3<D, ITEM, Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusConvert(type: Int, clazz: Class<D>, convert: (D, ITEM, Int) -> Unit): TypeSupportAdaper<ITEM> {
val hc = HolderDataBindingClass(type, clazz = clazz) {
HolderConvert<ITEM, D> { d, i, p ->
convert(d, i, p)
}
}
hc.adaper = this
typeDataBindings.put(hc.t, hc)
return this
}
/**
* 同时添加 [页面创建时] ,[绑定页面时]回调
* @param clazz Class<D>
* @param viewCreate Function2<[@kotlin.ParameterName] D, [@kotlin.ParameterName] Int, Unit>
* @param convert Function3<[@kotlin.ParameterName] D, [@kotlin.ParameterName] ITEM, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusAll(clazz: Class<D>, viewCreate: (dataBinding: D, type: Int) -> Unit, convert: (dataBinding: D, item: ITEM, postion: Int) -> Unit): TypeSupportAdaper<ITEM> = plusAll(ZERO, clazz, viewCreate, convert)
/**
* 同时添加 [页面创建时] ,[绑定页面时]回调。基于类型[ViewType]
* @param type Int itemType 不同item的;类型
* @param clazz Class<D> dataBinding 的 class 用来反射获取实例
* @param viewCreate Function2<[@kotlin.ParameterName] D, [@kotlin.ParameterName] Int, Unit> 相当于RecyclerView.Adapter.onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
* @param convert Function3<[@kotlin.ParameterName] D, [@kotlin.ParameterName] ITEM, [@kotlin.ParameterName] Int, Unit> 相当于RecyclerView.Adapter.onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
* @return TypeSupportAdaper<ITEM>
*/
fun <D : ViewDataBinding> plusAll(type: Int, clazz: Class<D>, viewCreate: (dataBinding: D, type: Int) -> Unit, convert: (dataBinding: D, item: ITEM, postion: Int) -> Unit): TypeSupportAdaper<ITEM> {
val hc = HolderDataBindingClass<ITEM, D>(type = type, clazz = clazz) {
HolderConvert { d, i, p ->
convert(d, i, p)
}
}
hc.holderViewCreate = HolderViewCreate { d, t ->
viewCreate(d, t)
}
typeDataBindings.put(hc.t, hc)
return this
}
/**
* 添加一个[全局数据绑定]时的回调
* @param convert Function3<[@kotlin.ParameterName] ViewDataBinding, [@kotlin.ParameterName] ITEM, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun joinConvert(convert: (dataBinding: ViewDataBinding, item: ITEM, postion: Int) -> Unit): TypeSupportAdaper<ITEM> {
allConvertMethod = convert;
return this
}
/**
* 添加一个[全局数据页面创建]时的回调
* @param convert Function3<[@kotlin.ParameterName] ViewDataBinding, [@kotlin.ParameterName] Int, ViewGroup, Unit>
* @return TypeSupportAdaper<ITEM>
*/
fun joinViewCreate(convert: (dataBinding: ViewDataBinding, type: Int, ViewGroup) -> Unit): TypeSupportAdaper<ITEM> {
allViewCreateMethod = convert;
return this
}
/**
* 包裹着当前类型的databinding类型
* @param ITEM
* @property type Int
* @property r Class<*>
* @property holderConvert HolderConvert<ITEM, *>
* @property holderViewCreate HolderViewCreate<*>?
* @constructor
*/
class HolderDataBindingClass<ITEM, D : ViewDataBinding>(type: Int, clazz: Class<D>, ct: (() -> HolderConvert<ITEM, D>)?) {
lateinit var adaper: TypeSupportAdaper<ITEM>
val t = type;
val r = clazz
val holderConvert: HolderConvert<ITEM, D>? = ct?.invoke()
var holderViewCreate: HolderViewCreate<D>? = null;
fun hodlerDataBindingClass() = r
// constructor(clazz: Class<D>, ct: () -> HolderConvert<ITEM, D>) : this(ZERO, clazz, ct)
//
// fun plusViewCreate(h: (dataBinding: D, type: Int) -> Unit): TypeSupportAdaper<ITEM> {
// holderViewCreate = HolderViewCreate { d, t ->
// h(d, t)
// }
// return adaper
// }
}
/**
* databinding创建时
* @param D : ViewDataBinding
* @property r Function2<D, [@kotlin.ParameterName] Int, Unit>
* @constructor
*/
class HolderViewCreate<D : ViewDataBinding>(run: (D, type: Int) -> Unit) {
val r = run
fun convertData(vdv: ViewDataBinding, type: Int) {
r(vdv as D, type);
}
}
/**
* 数据装换
* @param ITEM
* @param D : ViewDataBinding
* @property r Function3<D, ITEM, [@kotlin.ParameterName] Int, Unit>
* @constructor
*/
class HolderConvert<ITEM, D : ViewDataBinding>(run: (D, ITEM, p: Int) -> Unit) {
val r = run
fun convertData(vdv: ViewDataBinding, e: ITEM, position: Int) {
r(vdv as D, e, position);
}
}
companion object {
const val ZERO = 0
fun <ITEM, D : ViewDataBinding> build(datas: List<ITEM>, clazz: Class<D>, run: (dataBinding: D, item: ITEM, postion: Int) -> Unit) = TypeSupportAdaper(datas).plusConvert(clazz = clazz, run)
fun <ITEM, D : ViewDataBinding> build(datas: List<ITEM>, clazz: Class<D>, cRun: (D, Int) -> Unit, run: (dataBinding: D, item: ITEM, postion: Int) -> Unit) = TypeSupportAdaper(datas).plusAll(clazz = clazz, cRun, run)
fun <ITEM, D : ViewDataBinding> build(type:Int,datas: List<ITEM>, clazz: Class<D>, cRun: (D, Int) -> Unit, run: (dataBinding: D, item: ITEM, postion: Int) -> Unit) = TypeSupportAdaper(datas).plusAll(type,clazz = clazz, cRun, run)
}
}
/**
* 处理因为,itemtype 列表不一致的情况的adapter
* @param ListItem
* @constructor
*/
abstract class ListSetAdapter<ListItem>(list: List<ListItem>) : ListAbstacyAdapter<ListItem>(list) {
final override fun convert(d: ViewDataBinding, entity: ListItem, postion: Int) {
// Log.i("convert", ": ListSetAdapter , $postion , $d")
beanSet.invoke(d, entity!!)
convertData(d, entity, postion)
}
abstract fun convertData(d: ViewDataBinding, entity: ListItem, postion: Int)
}
abstract class ListAbstacyAdapter<ListItem>(var list: List<ListItem>) : RecyclerView.Adapter<DataBindingViewHolder>(), IChangeData<ListItem> {
init {
setHasStableIds(true)
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
final override fun onBindViewHolder(holder: DataBindingViewHolder, position: Int) {
convert(holder.getDataBinding(), list[position], position)
}
abstract fun convert(d: ViewDataBinding, item: ListItem, postion: Int);
override fun getItemCount() = list.size
override fun changeData(datas: List<ListItem>) {
(list as? ArrayList)?.apply {
clear()
addAll(datas)
}
}
}
val beanSet = { d: ViewDataBinding, entity: Any ->
d.entitySet("bean",entity.javaClass,entity)
}
/**
* 返回一个adapter,不做任何数据绑定
* @receiver T
* @param c Class<D>
* @return TypeSupportAdaper<[@kotlin.ParameterName] I>
*/
fun <T : ISource<I>, D : ViewDataBinding, I> T.adapter(c: Class<D>) = adapter(c, null);
/**
* 返回一个adapter,有一个onBindView
* @receiver T
* @param c Class<D>
* @param run Function3<[@kotlin.ParameterName] D, [@kotlin.ParameterName] I, [@kotlin.ParameterName] Int, Unit>?
* @return TypeSupportAdaper<[@kotlin.ParameterName] I>
*/
fun <T : ISource<I>, D : ViewDataBinding, I> T.adapter(c: Class<D>, run: ((dataBinding: D, item: I, postion: Int) -> Unit)?) = TypeSupportAdaper.build(realData(), c, run
?: { _, _, _ -> })
/**
* 返回一个adapter ,有一个onCreatView,有一个onBindView
* @receiver T
* @param c Class<D>
* @param cRun Function2<D, Int, Unit>
* @param run Function3<[@kotlin.ParameterName] D, [@kotlin.ParameterName] I, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<[@kotlin.ParameterName] I>
*/
fun <T : ISource<I>, D : ViewDataBinding, I> T.adapter(c: Class<D>, cRun: (D, Int) -> Unit, run: (dataBinding: D, item: I, postion: Int) -> Unit) = TypeSupportAdaper.build(realData(), c, cRun, run)
/**
* 返回一个adapter ,有一个onCreatView,有一个onBindView
* @receiver T
* @param type Int
* @param c Class<D>
* @param cRun Function2<D, Int, Unit>
* @param run Function3<[@kotlin.ParameterName] D, [@kotlin.ParameterName] I, [@kotlin.ParameterName] Int, Unit>
* @return TypeSupportAdaper<[@kotlin.ParameterName] I>
*/
fun <T : ISource<I>, D : ViewDataBinding, I> T.adapter(type:Int,c: Class<D>, cRun: (D, Int) -> Unit, run: (dataBinding: D, item: I, postion: Int) -> Unit) = TypeSupportAdaper.build(type,realData(), c, cRun, run)
class SourceImpl<Item>(var datas: List<Item> = ArrayList()) : ISource<Item> {
override fun realData() = datas
}
interface ISource<Item> {
fun realData(): List<Item>
}
|