与 Kotlin 代表一起享受更多乐趣

ssu*_*ukk 5 delegates android-lifecycle kotlin android-databinding

如果您了解 Google 的实验性 Android 架构组件,您可能就知道MutableLiveData。为了让它使用起来更有趣,我带来了:

\n\n
class KotlinLiveData<T>(val default: T) {\n    val data = MutableLiveData<T>()\n\n    operator fun getValue(thisRef: Any?, property: KProperty<*>):T {\n        return data.value ?: default\n    }\n\n    operator fun setValue(thisRef: Any?, property: KProperty<*>, value:T) {\n        if (Looper.myLooper() == Looper.getMainLooper()) {\n            data.value = value\n        } else {\n            data.postValue(value)\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我可以:

\n\n
var name : String by KotlinLiveData("not given")\nname = "Chrz\xc4\x99szczybrz\xc4\x99czykiewicz"\n
Run Code Online (Sandbox Code Playgroud)\n\n

但可惜 - 这使得data需要注册的内容Observer无法访问:

\n\n
name.data.observe(this, nameObserver) // won\'t work :(\n
Run Code Online (Sandbox Code Playgroud)\n\n

知道我是否能以某种方式得到它吗?

\n

hot*_*key 3

您可以访问该属性的委托对象MutableLiveData<T>从中获取:

inline fun <reified R> KProperty<*>.delegateAs<R>(): R? {
    isAccessible = true
    return getDelegate() as? R
}
Run Code Online (Sandbox Code Playgroud)

那么用法就是:

::name.delegateAs<KotlinLiveData<String>>?.data?.observe(this, nameObserver)
Run Code Online (Sandbox Code Playgroud)

要引用成员属性,请使用this::namesomeInstance::name

此解决方案要求您添加 Kotlin 反射 APIkotlin-reflect作为项目的依赖项。此外,由于类型擦除,该.delegateAs<KotlinLiveData<String>>调用不是类型安全的:它只能检查委托是否为KotlinLiveData<*>,但不能检查其类型参数是否为String