Android 与 Kotlin、BaseObservable 和自定义委托的数据绑定
Android data binding with Kotlin, BaseObservable, and a custom delegate
我正在尝试编写一个自定义委托来清理 Kotlin 中数据绑定的语法 class。这将消除为我可能想要观察的每个 属性 定义自定义 getter 和 setter 的需要。
Kotlin 中的标准实现如下所示:
class Foo : BaseObservable() {
var bar: String
@Bindable get() = bar
set(value) {
bar = value
notifyPropertyChanged(BR.bar)
}
}
显然,对于很多属性,这个 class 会变得非常冗长。相反,我想要的是将其抽象为一个委托,如下所示:
class BaseObservableDelegate(val id: Int, private val observable: BaseObservable) {
@Bindable
operator fun getValue(thisRef: Any, property: KProperty<*>): Any {
return thisRef
}
operator fun setValue(thisRef: Any, property: KProperty<*>, value: Any) {
observable.notifyPropertyChanged(id)
}
}
然后,扩展 BaseObservable 的 class 可以返回到单行变量声明:
class Foo : BaseObservable() {
var bar by BaseObservableDelegate(BR.bar, this)
}
问题在于,如果 Foo class 中没有 @Bindable 注释,则不会在 BR 中为 bar 生成 属性Id。我不知道用于生成该 属性 id.
的任何其他注释或方法
如有任何指导,我们将不胜感激。
您可以在不提供主体的情况下注释默认的 getter 或 setter。
var bar: String by Delegates.observable("") { prop, old, new ->
notifyPropertyChanged(BR.bar)
}
@Bindable get
有一个快捷方式 annotation use-site target 可以做同样的事情。
@get:Bindable var bar: String by Delegates.observable("") { prop, old, new ->
notifyPropertyChanged(BR.bar)
}
除已接受的答案外 - 有时您需要在构造函数中传递变量。做起来也很容易。
class Foo(_bar: String) : BaseObservable() {
@get:Bindable var bar by Delegates.observable(_bar) { _, _, _ ->
notifyPropertyChanged(BR.bar)
}
}
有时我们必须使用 parcel 保存对象,我在使用 delegete 时遇到了一些问题,所以代码如下所示:
@Parcelize
class Foo(private var _bar: String) : BaseObservable(), Parcelable {
@IgnoredOnParcel
@get:Bindable var bar
get() = _bar
set(value) {
_bar = value
notifyPropertyChanged(BR.bar)
}
}
我正在尝试编写一个自定义委托来清理 Kotlin 中数据绑定的语法 class。这将消除为我可能想要观察的每个 属性 定义自定义 getter 和 setter 的需要。
Kotlin 中的标准实现如下所示:
class Foo : BaseObservable() {
var bar: String
@Bindable get() = bar
set(value) {
bar = value
notifyPropertyChanged(BR.bar)
}
}
显然,对于很多属性,这个 class 会变得非常冗长。相反,我想要的是将其抽象为一个委托,如下所示:
class BaseObservableDelegate(val id: Int, private val observable: BaseObservable) {
@Bindable
operator fun getValue(thisRef: Any, property: KProperty<*>): Any {
return thisRef
}
operator fun setValue(thisRef: Any, property: KProperty<*>, value: Any) {
observable.notifyPropertyChanged(id)
}
}
然后,扩展 BaseObservable 的 class 可以返回到单行变量声明:
class Foo : BaseObservable() {
var bar by BaseObservableDelegate(BR.bar, this)
}
问题在于,如果 Foo class 中没有 @Bindable 注释,则不会在 BR 中为 bar 生成 属性Id。我不知道用于生成该 属性 id.
的任何其他注释或方法如有任何指导,我们将不胜感激。
您可以在不提供主体的情况下注释默认的 getter 或 setter。
var bar: String by Delegates.observable("") { prop, old, new ->
notifyPropertyChanged(BR.bar)
}
@Bindable get
有一个快捷方式 annotation use-site target 可以做同样的事情。
@get:Bindable var bar: String by Delegates.observable("") { prop, old, new ->
notifyPropertyChanged(BR.bar)
}
除已接受的答案外 - 有时您需要在构造函数中传递变量。做起来也很容易。
class Foo(_bar: String) : BaseObservable() {
@get:Bindable var bar by Delegates.observable(_bar) { _, _, _ ->
notifyPropertyChanged(BR.bar)
}
}
有时我们必须使用 parcel 保存对象,我在使用 delegete 时遇到了一些问题,所以代码如下所示:
@Parcelize
class Foo(private var _bar: String) : BaseObservable(), Parcelable {
@IgnoredOnParcel
@get:Bindable var bar
get() = _bar
set(value) {
_bar = value
notifyPropertyChanged(BR.bar)
}
}