当 Adapter 遇上 Kotlin DSL,无比简单的调用方式

早在去年的时候我就提到过使用工厂的方式获取 Adapter 而不是为每个 Adapter 定义一个类文件。这样的好处是,对于不是那么复杂的 Adapter 可以节省大量的代码,提升开发效率和解放双手,同时更好的支持多类型布局效果。

1、Kotlin DSL 和 Adapter 工厂方法

可以把 Kotlin DSL 当作构建者使用。这里有一篇不错的文章,想了解的可以阅读下,

www.ximedes.com/2020-04-21/…

Kotlin DSL 是拓展函数的延申,比如我们常用的 with 等函数就是函数的拓展,

public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}
复制代码

这里是泛型 T 的拓展。这里的 T 可以类比到 Java 构建者模式中的 Builder,通过方法接收外部参数之后调用 build() 方法创建一个最终的对象即可。

对于 Adapter 工厂方法,之前我是通过如下方式使用的,

fun <T> getAdapter(
    @LayoutRes itemLayout:Int,
    converter: (helper: BaseViewHolder, item: T) -> Unit,
    data: List<T>
): Adapter<T> = Adapter(itemLayout, converter, data)

class Adapter<T>(
    @LayoutRes private val layout: Int,
    private val converter: (helper: BaseViewHolder, item: T) -> Unit,
    val list: List<T>
): BaseQuickAdapter<T, BaseViewHolder>(layout, list) {
    override fun convert(helper: BaseViewHolder, item: T) {
        converter(helper, item)
    }
}
复制代码

也就是每次想要得到 Adapter 的时候只要调用 getAdapter() 方法即可。这种封装方式比较简陋,支持的功能有限。后来慢慢采用了 Kotlin DSL 之后,我封装了 Kotlin DSL 风格的工厂方法。采用 Kotlin DSL 风格之后更加优雅和方便快捷,同时更好的支持多类型布局效果。

2、使用

2.1 引入依赖

首先,该项目依赖于 BRVAH,所以,你需要引入该库之后菜可以使用。BRVAH 可以说是目前开源的最好用的 Adapter,我们没必要再另起炉灶自己再造轮子。这个框架设计最好地方在于通过 SpareArray 收集了 ViewHolder 控件,从而避免了自定义 ViewHolder,这是我们框架设计的基础思想。

该项目已经上传到了 MavenCentral,你需要先在项目中引入该仓库,

allprojects {
    repositories {
        mavenCentral()
    }
}
复制代码

然后在项目中添加如下依赖,

implementation "com.github.Shouheng88:xadapter:${latest_version}"
复制代码

2.2 使用 Adapter 工厂方法

使用 xAdapter 之后,当你需要定义一个 Adapter 的时候,你无需单独创建一个类文件,只需要通过 createAdapter() 方法获取一个 Adapter,

adapter = createAdapter {
    withType(Item::class.java, R.layout.item_eyepetizer_home) {
        // Bind data with viewholder.
        onBind { helper, item ->
            helper.setText(R.id.tv_title, item.data.title)
            helper.setText(R.id.tv_sub_title, item.data.author?.name + " | " + item.data.category)
            helper.loadCover(requireContext(), R.id.iv_cover, item.data.cover?.homepage, R.drawable.recommend_summary_card_bg_unlike)
            helper.loadRoundImage(requireContext(), R.id.iv_author, item.data.author?.icon, R.mipmap.eyepetizer, 20f.dp2px())
        }
        // Item level click and long click events.
        onItemClick { _, _, position ->
            adapter?.getItem(position)?.let {
                toast("Clicked item: " + it.data.title)
            }
        }
    }
}
复制代码

在这种新的调用方式中,你需要通过 withType() 方法指定数据类型及其对应的布局文件,然后在 onBind() 方法中即可实现数据到 ViewHolder 的绑定操作。这里的 onBind() 方法的使用与 BRVAH 中的 convert() 方法使用一致,可以通过阅读该库了解如何使用。总之,xAapter 在 BRVAH 的基础上做了二次封装,可以说,比简单更简单。

xAdapter 支持为每个 ViewHolder 绑定点击和长按事件,同时也支持为 ViewHolder 上的某个单独的 View 添加点击和长按事件。使用方式如上所示,只需要添加 onItemClick() 方法并实现自己的逻辑即可。其他的点击事件可以参考项目的示例代码。

效果,

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享