以前也写过 RecyclerView 的 base 层基类,但是随着发展,现在这不都是 Kotlin 和 DataBinding 了嘛,尤其是 DataBinding 这天然是 ViewHolder 的替代品啊,有了 ViewHolder 我们不用再写单独的 ViewHolder 了
看了一些其他的用 DataBinding 写的 BaseAdapter、BaseViewHolder,发现过于复杂, 用起来不是很友好,Adapter、ViewHolder 本身逻辑就很简单了,我们不要反而搞得更复杂, 代码封装起来还不是为了更简单,更省事,不要为了封装而封装,我到时觉得封装的过于彻底,反倒是不利于阅读,扩展,修改,适度就好
Kotlin 配置 DataBinding 环境请看:
下面请大家来品鉴我们的方案:
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<Any> = mutableListOf()) : RecyclerView.Adapter<BaseViewHolder>() {
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 传进去
这样写更灵活一些,在此处方便修改,方便写任何代码
注意点啊
-
ViewDataBinding 是 DataBinding 自动产生类型的基类,是可以转换为具体的类型的,也可以进行类型判断
-
ViewDataBinding 通过 setVariable 可以传递参数,这样不用再强转 ViewDataBinding 类型了
-
BR 会有对个包引用,请使用范围最广的那个
-
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);
}
}
网友评论