IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 运用Kotlin 扩展高阶函数写RecycleView Adapter(结合DataBinding) -> 正文阅读

[移动开发]Android 运用Kotlin 扩展高阶函数写RecycleView Adapter(结合DataBinding)

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>
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-12 00:07:14  更:2022-01-12 00:08:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:00:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码