我是怎么开始去使用它的
开始使用它的原因
Data Binding出现也有几年了,一直没有去用它的主要原因是它的写法让我觉得会把业务逻辑与界面过度耦合在一起。但前段时间还是试用了一下。
会想去用它一共有四个原因。
一是说到底没有用过,感觉如果与他人讨论到它难免有空谈的心虚感,毕竟一项技术是好是坏还是使用过后再去评论比较有底气。
二是想先引入Data Binding,再在项目中结合它尝试MVVM模式,毕竟Data Binding的使用方式看起来与MVVM相当的切合。
三是高效。我们通过findViewById(id)
的方式找到控件并赋值,每次都会对视图树进行循环和递归直到找到,而Data Binding只会遍历一次视图树,然后找出所有需要绑定的控件并进行赋值,相比之下要高效很多。
四是我想既然有不少人推崇它,那么除了它明显的耦合的问题之外,应该有其他的优势,并且这种优势使得它所带来的代码的耦合度问题也可以接受。
基于这几个原因,我先在自己业余之下写的一个小项目中去使用它。
我的封装
我这个项目的地址为:https://github.com/msdx/gradle-doc-apk 。这是一个在手机上方便浏览Gradle文档的应用程序,业务逻辑非常简单,主要是几个简单的列表界面再加上一个显示文档章节内容的WebView,使用到Data Binding的就是里面的列表界面了。
一个项目里的封装,不应该脱离于项目本身的使用场景。不需要过度设计,而是要简洁高效。
在我的这个应用里,列表的逻辑都很简单,每个列表类型单一,每个Item里都只需要一个变量,并且除了图片加载之外,数据绑定在xml中就可以表达。所在在调用的代码中,我并不需要关心item布局所对应的具体的ViewDataBinding类型。因此,在这里我的封装也很简单。
我主要封装了一个ViewHolder和一个Adapter。ViewHolder里只需要持有一个ViewDataBinding成员,代码如下:
class BindingHolder(val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root)
由于列表简单,不需要再在绑定数据时执行其他的逻辑,并且只有一个Data Binding的变量,所以在它的构造方法中传入item布局及BR id,然后在里面实现onCreateViewHolder(parent: ViewGroup, viewType: Int)
及onBindViewHolder(holder: BindingHolder, position: Int)
方法,完整代码如下:
class BaseListAdapter<D>(
private val layoutId: Int,
private val brId: Int
) : RecyclerView.Adapter<BindingHolder>() {
private val list = ArrayList<D>()
var onItemClickListener: OnItemClickListener<D>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder {
val inflater = LayoutInflater.from(parent.context)
val binding: ViewDataBinding = DataBindingUtil.inflate(inflater, layoutId, parent, false)
val holder = BindingHolder(binding)
return holder.apply {
itemView.setOnClickListener {
val position = adapterPosition
onItemClickListener?.onItemClick(it, position, list[position])
}
}
}
override fun getItemCount() = list.size
override fun onBindViewHolder(holder: BindingHolder, position: Int) {
holder.binding.setVariable(brId, list[position])
holder.binding.executePendingBindings()
}
fun update(list: List<D>) {
this.list.clear()
this