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