DSL+Rxjava手撸DataBinding

2017-10-16  本文已影响89人  RetroX

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没有考虑到
但是希望可以给大家带来些许灵感

上一篇 下一篇

猜你喜欢

热点阅读