我正在开发一个Android应用,我想实现MVVM模式,这几乎是Google推动的标准,但是,如果可能的话,我想避免使用Android数据绑定库,因为我讨厌自动生成XML魔术。
我已经尝试使用Jake Wharton的数据绑定库以及一些有用的扩展方法在RxJava(Kotlin)中实现类似于数据绑定的功能。
我的问题是,这是做事情的正确方法吗?这足以在生产中使用吗?这种方法是否有潜在的问题,我以后看不到?
基本上,我是这样实现的:
我有一个MvvmFragment
(有一个类似的活动类),它负责设置和管理CompositeDisposable
对象的生命周期。
然后,在我的ViewModel
(属于Android Arch ViewModel软件包的一部分)中,我具有将要这样声明的所有字段:
var displayName = BindableVar("")
var email = BindableVar("")
var signInProvider = BindableVar<AuthProvider>(defaultValue = AuthProvider.PASSWORD)
(附带说明-由于Rx不允许使用null值,因此我不确定如何处理默认概念没有真正意义的对象的默认情况,例如{{1} }}
AuthProvider
类的实现如下:
BindableVar
使用Jake Wharton的RxBindings库,我在此之上创建了一些有用的扩展方法,例如:
class BindableVar<T>(defaultValue: T) {
var value: T = defaultValue
set(value) {
field = value
observable.onNext(value)
}
var observable = BehaviorSubject.createDefault(value)!!
}
使用这些扩展方法,然后在Fragment初始化上获取fun Disposable.addTo(compositeDisposable: CompositeDisposable): Disposable {
compositeDisposable.add(this)
return this
}
fun TextView.bindTextTo(string: BindableVar<String>): Disposable {
return string.observable.subscribe(this.text())
}
fun View.bindVisibilityTo(visibility: Int) {
// ... not shown
}
fun ImageView.bindImageUriTo(
src: BindableVar<Uri>, @DrawableRes placeholder: Int? = null
): Disposable {
return if (placeholder == null) {
src.observable.subscribe {
GlideApp.with(context).load(it).into(this)
}
} else {
src.observable.subscribe {
GlideApp.with(context).load(it).placeholder(placeholder).into(this)
}
}
}
实例,并调用方法ViewModel
,如下所示:
initBindings()
我想避免花一个星期来充实这种体系结构,然后突然意识到存在一些无法轻易解决的关键问题,或者其他一些隐患。我应该只使用基于XML的数据绑定吗?我已经听到了很多关于单元测试的困难以及重复使用代码的困难的抱怨。