Android系统自带的DataBinding基于复杂的apt,坑巨多,最近逐步弃坑原生DataBinding框架,但是又很喜欢MVVM的这种数据绑定的架构。最近学习DSL后,对于DataBinding有了一种新的实现想法。
大概来讲原型就是两个拓展函数
fun PublishSubject<String>.bind(view: TextView) {
this.subscribe {
view.setText(it)
}
}
fun PublishSubject<String>.update(value: String?) {
this.onNext(value)
}
基于rxjava的Subject进行数据流桥接即可
(PS:当然在应用场景下,可能需要你去管理一下生命周期,当然我也在探索使用LiveData进行数据绑定的方法)
一个Demo,用来写adapter的一个VH
class ClassItemViewHolder(val itemUI: ClassItemUi, itemView: View?) : RecyclerView.ViewHolder(itemView) {
class ClassItemUi : AnkoComponent<ViewGroup> {
val location = PublishSubject.create<String>()
val courseName = PublishSubject.create<String>()
val teacherName = PublishSubject.create<String>()
override fun createView(ui: AnkoContext<ViewGroup>): View {
with(ui) {
val itemView = cardView {
radius = 10f
cardElevation = 8f
// horizontalPadding = dip(16)
setCardBackgroundColor(Color.parseColor("#8071FF"))
// backgroundColor = Color.parseColor("#0ac3d5")
verticalLayout {
padding = dip(16)
textView("课程名") {
textSize = 20f
courseName.bind(this)
}.lparams {
gravity = Gravity.START
}
textView("地点") {
textSize = 20f
location.bind(this)
}.lparams {
gravity = Gravity.END
}
textView("老师名字") {
textSize = 20f
teacherName.bind(this)
}.lparams {
gravity = Gravity.END
}
}
}.apply {
layoutParams = with(FrameLayout.LayoutParams(matchParent, wrapContent)) {
leftMargin = dip(4)
rightMargin = dip(4)
topMargin = dip(8)
this
}
}
itemView.tag = ClassItemViewHolder(this@ClassItemUi, itemView)
return itemView
}
}
}
}
在调用的时候
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder?, position: Int) {
val course = courseList[position]
if (viewHolder is ClassItemViewHolder){
viewHolder.itemUI.apply {
courseName.update(course.coursename)
val locationStr = course.arrange?.get(0)?.room
location.update(locationStr)
teacherName.update(course.teacher)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ClassItemViewHolder.ClassItemUi().createView(AnkoContext.Companion.create(parent.context,parent)).tag as ClassItemViewHolder
}
使用update方法即可更新绑定的数据
当然这种思维不局限于DSL,xml里面写find出来绑上也可以
这是一个手撸DataBinding的原型,还有很多case没有考虑到
但是希望可以给大家带来些许灵感