如果您了解Google的实验性Android架构组件,您可能知道MutableLiveData
。试着让它更有趣使用我来了:
class KotlinLiveData<T>(val default: T) {
val data = MutableLiveData<T>()
operator fun getValue(thisRef: Any?, property: KProperty<*>):T {
return data.value ?: default
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value:T) {
if (Looper.myLooper() == Looper.getMainLooper()) {
data.value = value
} else {
data.postValue(value)
}
}
}
然后我可以:
var name : String by KotlinLiveData("not given")
name = "Chrzęszczybrzęczykiewicz"
但是唉 - 这需要data
,即注册Observer
无法访问:
name.data.observe(this, nameObserver) // won't work :(
知道我是否能以某种方式得到它?
答案 0 :(得分:1)
您可以实现的最简单方法是将委托者设置为字段,例如:
@JvmField val dataOfName = KotlinLiveData("not given")
var name : String by dataOfName
然后你可以在课堂上使用实时数据,例如:
dataOfName.data.observe(this, nameObserver)
name = "Chrzęszczybrzęczykiewicz"
OR 您可以编写一些语法,例如:
var name : String by live("not given").observe(this, nameObserver)
注意您也可以懒散地nameObserver
,例如:
val observers by lazy{mutableListOf<Observer>()}
var name : String by live("not given").observe(this){data->
observers.forEach{it.dataChanged(data)}
}
然后你可以做如下的事情:
observers+= nameObserver;
name = "Chrzęszczybrzęczykiewicz"
observers-= nameObserver;
答案 1 :(得分:1)
您可以access the delegate object获取该属性并从中获取Collections.sort(list);
:
MutableLiveData<T>
然后用法是:
inline fun <reified R> KProperty<*>.delegateAs<R>(): R? {
isAccessible = true
return getDelegate() as? R
}
要引用成员媒体资源,请使用::name.delegateAs<KotlinLiveData<String>>?.data?.observe(this, nameObserver)
或this::name
。
此解决方案要求您将Kotlin反射API kotlin-reflect
添加为项目的依赖项。此外,由于类型擦除,someInstance::name
调用不是类型安全的:它只能检查委托是.delegateAs<KotlinLiveData<String>>
,而不是它的类型参数是KotlinLiveData<*>
。
答案 2 :(得分:0)
感谢hotkey的解决方案,这里有一些更好的代码:
class KotlinLiveData<T>(val default: T, val liveData : MutableLiveData<T>? = null) {
val data = liveData ?: MutableLiveData<T>()
operator fun getValue(thisRef: Any?, property: KProperty<*>):T {
return data.value ?: default
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value:T) {
if (Looper.myLooper() == Looper.getMainLooper()) {
data.value = value
} else {
data.postValue(value)
}
}
}
inline fun <reified R> KMutableProperty0<*>.getLiveData(): MutableLiveData<R> {
isAccessible = true
return (getDelegate() as KotlinLiveData<R>).data
}
inline fun <reified R> KMutableProperty0<*>.observe(owner: LifecycleOwner, obs : Observer<R>) {
isAccessible = true
(getDelegate() as KotlinLiveData<R>).data.observe(owner,obs)
}
现在我可以:
someViewModel::name.observe(myActivity, Observer<String>{...})
与
someViewModel.name = "Kowalski, Leon"
按预期工作
此类允许使用带有Android数据绑定的LiveData。