Kotlin中如何正确监听普通变量的数值变化?
Kotlin 变量变更监听实现方案
失效原因
代码B无法触发回调的核心问题:
- 存在语法错误:
var myObserv String by Delegates.observable(...)缺少类型声明的冒号,正确写法为var myObserv: String by ... - 逻辑绑定不成立:
Delegates.observable仅会拦截被委托属性自身的写入操作。初始化时传入的myFilename仅会将当前值"OK"拷贝作为委托的初始值,myObserv和myFilename是两个完全独立的属性,修改myFilename时不会触碰myObserv的访问逻辑,自然无法触发回调。
正确实现方式
方式1:直接给目标变量加委托(最简便)
参照代码A的实现逻辑,直接给需要监听的目标变量加上Delegates.observable委托,所有对该变量的写入操作都会被委托拦截,自动触发回调:
// 直接对需要监听的变量定义委托,初始值设为目标值"OK" var myFilename: String by Delegates.observable("OK") { prop, old, new -> // 在此处编写值变化后的业务逻辑 println("属性${prop.name}从$old 修改为 $new") } // 测试 fun main() { myFilename = "test.txt" // 写入时会正常触发回调 }
方式2:自定义属性访问器
如果需要将变量的实际存储和监听逻辑解耦,可以自定义属性的getter/setter,在setter中手动判断值变化并执行通知逻辑:
// 内部实际存储值的私有变量 private var _myFilename = "OK" // 对外暴露的可访问属性 var myFilename: String get() = _myFilename set(newValue) { val oldValue = _myFilename _myFilename = newValue // 可选:判断值真的发生变化再触发逻辑,避免重复赋值触发无效回调 if (oldValue != newValue) { println("文件名从$oldValue 修改为 $newValue") } }
注意:普通变量的写入操作默认没有对外暴露拦截钩子,你只能监听自己可以定义访问逻辑的变量:要么直接给变量加observable委托,要么自定义它的setter。如果要监听的变量是第三方代码里定义的普通public var,且对方没有提供变更监听接口,Kotlin原生手段无法直接拦截它的修改。
内容的提问来源于stack exchange,提问作者HelloCW
相关产品推荐
相关产品推荐

