RecyclerView — Kotlin 配合 DataBinding 搭建 BaseAdapter、BaseViewHolder

以前也写过 RecyclerView 的 base 层基类,但是随着发展,现在这不都是 Kotlin 和 DataBinding 了嘛,尤其是 DataBinding 这天然是 ViewHolder 的替代品啊,有了 ViewHolder 我们不用再写单独的 ViewHolder 了

看了一些其他的用 DataBinding 写的 BaseAdapter、BaseViewHolder,发现过于复杂, 用起来不是很友好,Adapter、ViewHolder 本身逻辑就很简单了,我们不要反而搞得更复杂, 代码封装起来还不是为了更简单,更省事,不要为了封装而封装,我到时觉得封装的过于彻底,反倒是不利于阅读,扩展,修改,适度就好

Kotlin 配置 DataBinding 环境请看:

  • Kotlin 里面如何配置 DataBinding

下面请大家来品鉴我们的方案:

  • BW_Libs

BaseViewHolder

上面说过了,我打算用 DataBinding 完全替代 ViewHolder,平时我们写 ViewHolder 里面都是 finviewbyid 和赋值操作,这里我们把赋值放到 Adapter 里,这样有一个 BaseViewHolder 就能做到通用了

open class BaseViewHolder(var dataBinding: ViewDataBinding) : RecyclerView.ViewHolder(dataBinding.root) {}

OK ,简单不,这就可以了


BaseAdapter

BaseAdapter 里面主要逻辑就是通过 viewType 生成相关的 ViewDataBinding 赋值给 BaseViewHolder

我们在处理多类型时,在 getItemViewType 里直接返回对应的 layoutID,这样 BaseAdapter 基类就能执行统一的生成 BaseViewHolder 的逻辑了

getItemViewType 直接返回对应的 layoutID

    override fun getItemViewType(position: Int): Int {

        if (data.get(position) is Book) return R.layout.item_book
        if (data.get(position) is Cat) return R.layout.item_cat

        return R.layout.item_book
    }
abstract class BaseAdapter(var data: MutableList = mutableListOf()) : RecyclerView.Adapter() {

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): BaseViewHolder {
        return BaseViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent?.context), viewType, parent, false))
    }

    override fun getItemCount(): Int {
        return data.size
    }
}

activity 层使用

activity

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_base)

        var layoutManage = LinearLayoutManager(this)
        layoutManage.orientation = LinearLayoutManager.VERTICAL

        var adapter = StandarAdapter()
        adapter.data = getData()
        adapter.persenter = persenter

        recy_standar.layoutManager = layoutManage
        recy_standar.adapter = adapter
    }

StandarAdapter

class StandarAdapter : BaseAdapter() {

    lateinit var persenter: StandarPersenter

    override fun getItemViewType(position: Int): Int {

        if (data.get(position) is Book) return R.layout.item_book
        if (data.get(position) is Cat) return R.layout.item_cat

        return R.layout.item_book
    }

    override fun onBindViewHolder(holder: BaseViewHolder?, position: Int) {

        if (data.get(position) is Book) {
            holder?.dataBinding?.setVariable(BR.book, data.get(position) as Book)
            holder?.dataBinding?.setVariable(BR.persenter, persenter)
            holder?.dataBinding?.executePendingBindings()
        }
        if (data.get(position) is Cat) {
            holder?.dataBinding?.setVariable(BR.cat, data.get(position) as Cat)
            holder?.dataBinding?.setVariable(BR.persenter, persenter)
            holder?.dataBinding?.executePendingBindings()
        }
    }
}

我们把 ViewHolder 的赋值操作放到 onBindViewHolder 里面,考虑的是不光可以通过 DataBinding 传递数据,还可以传递逻辑操作对象,比如点击就不用再 onclicklistener ,我们直接把 persenter 传进去

这样写更灵活一些,在此处方便修改,方便写任何代码


注意点啊

  1. ViewDataBinding 是 DataBinding 自动产生类型的基类,是可以转换为具体的类型的,也可以进行类型判断

  2. ViewDataBinding 通过 setVariable 可以传递参数,这样不用再强转 ViewDataBinding 类型了

  3. BR 会有对个包引用,请使用范围最广的那个

  4. ViewDataBinding 的数据类和 kotlin 的 Data 冲突,我这里数据类型都是用 java 写的,按照 DataBinding 对数据类型的要求编写

数据类型

public class Book extends BaseObservable {

    public String name;
    public int price;

    public Book() {
    }

    public Book(String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }

    @Bindable
    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
        notifyPropertyChanged(BR.price);
    }
}

你可能感兴趣的:(RecyclerView — Kotlin 配合 DataBinding 搭建 BaseAdapter、BaseViewHolder)