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/122414329icon-default.png?t=LBL2https://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>
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐