-
-
Save xingstarx/ccba100649b46bf25407a498bbe18a33 to your computer and use it in GitHub Desktop.
Kotlin observable properties
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
** 为KProperty0添加一个扩展函数addObserver(),用来监听当值发生变化的时候刷新observer代码块 | |
**/ | |
fun <T> KProperty0<T>.addObserver(observer: (T) -> Unit) { | |
(getDelegate(this) as ObservableProperty<T>?)?.addObserver(observer) | |
} | |
private fun <T> getDelegate(kProperty: KProperty0<T>) : Any? { | |
val owner = (kProperty as PropertyReference).owner | |
val containerClass: Class<*> | |
try { | |
containerClass = (owner!!::class.members as ArrayList).firstOrNull { it.name == "jClass" }?.call(owner) as Class<*> | |
} catch (e: Exception) { | |
throw IllegalArgumentException("No such property 'jClass'") | |
} | |
containerClass.declaredFields.firstOrNull { it.name == kProperty.name + "\$delegate" }?.let { field -> | |
field.isAccessible = true | |
// try { | |
// val modifyFiled = field.javaClass.getDeclaredField("modifiers") | |
// modifyFiled.isAccessible = true | |
// modifyFiled.setInt(field, modifyFiled.getInt(field) and Modifier.FINAL.inv()) | |
// } catch (e: NoSuchFieldException) { | |
// e.printStackTrace() | |
// } | |
return field.get(kProperty.boundReceiver) | |
} | |
return null | |
} | |
open class ObservableProperty<T>(v: T) : ReadWriteProperty<Any?, T> { | |
val observers: MutableSet<(T) -> Unit> = LinkedHashSet() | |
private var value: T = v | |
override fun getValue(thisRef: Any?, property: KProperty<*>): T { | |
return value | |
} | |
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { | |
this.value = value | |
observers.forEach { it(value) } | |
} | |
fun addObserver(observer: (T) -> Unit) { | |
observers.add(observer) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
原来的这段代码用的是
发现不稳定,会存在报错的情况,所以用java反射的方式来获取delegate对象