If you know Google's experimental Android Architecture Components, you probably know MutableLiveData
. Trying to make it a bit more fun to use I came with:
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)
}
}
}
And then I can:
var name : String by KotlinLiveData("not given")
name = "Chrzęszczybrzęczykiewicz"
But alas - that makes data
which is needed i.e. to register Observer
inaccessible:
name.data.observe(this, nameObserver) // won't work :(
Any idea if I can get it somehow?
You can access the delegate object of the property and get the MutableLiveData<T>
from it:
inline fun <reified R> KProperty<*>.delegateAs<R>(): R? {
isAccessible = true
return getDelegate() as? R
}
Then the usage is:
::name.delegateAs<KotlinLiveData<String>>?.data?.observe(this, nameObserver)
To reference a member property, use this::name
or someInstance::name
.
This solution requires you to add the Kotlin reflection API, kotlin-reflect
, as a dependency to your project. Also, due to the type erasure, the .delegateAs<KotlinLiveData<String>>
call is not type-safe: it can only check that the delegate is KotlinLiveData<*>
but not that its type argument is String
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With