Android KTX:如何覆盖 Kotlin 添加的 属性 扩展
Android KTX: how to override Kotlin added property extension
我正在尝试覆盖 Kotlin 中的 View.setRotation() 方法。
由于AndroidKTX已经提供了属性分机"rotation",来电者只需拨打
viewObject.rotation = 90.0f
旋转视图。
但是,我想在用户改变旋转时添加一些额外的操作,比如
override fun setRotation(newRotation: Float) {
if (rotation == newRotation)
return
rotation = newRotation
doSomethingElse()
}
这会因为 Whosebug 错误而崩溃。
所以,我必须添加一些额外的代码来实现目标:
private var _rotation: Float = 0.0f
override fun setRotation(newRotation: Float) {
if (_rotation == newRotation) {
return
}
_rotation = newRotation
updateRotationInternally()
}
private fun updateRotationInternally() {
super.setRotation(_rotation)
doSomethingElse()
}
这行得通,但我想知道是否还有其他更优雅的方法,比如 "override the property extension setter"?
我不同意您实施的一个方面:您的 return
快捷方式。您假设使用现有旋转值调用 setRotation()
无效。如果 View
的官方 Google 版本确实如此,我不会感到惊讶,但据我们所知,这在某些 Oppo 设备 运行 修改后的版本上并不是一个安全的假设Android 8.0。尽量不要假设你没有写的东西的行为。如果你想在新旧旋转相等时跳过doSomethingElse()
,那很好。
我猜你的 setRotation()
函数在 View
的某个子类中。如果是这样,并考虑到我的上述抱怨,这是我能想到的最简单的方法:
class Bar : View() {
override fun setRotation(f: Float) {
val needSomething = getRotation() != f
super.setRotation(f)
if (needSomething) doSomethingElse()
}
fun doSomethingElse() {
println("got here!")
}
}
我的整体测试代码是在 a Kotlin scratchpad 中完成的(在 Android 之外),所以我用一个假的 View
实现和假的 rotation
扩展 [=34] 进行了测试=]:
open class View {
private var r: Float = 0.0f
open fun setRotation(f: Float) {
r = f
}
fun getRotation() = r
}
var View.rotation: Float
get() = getRotation()
set(value) = setRotation(value)
class Bar : View() {
override fun setRotation(f: Float) {
val needSomething = getRotation() != f
super.setRotation(f)
if (needSomething) doSomethingElse()
}
fun doSomethingElse() {
println("got here!")
}
}
fun main() {
val bar = Bar()
bar.rotation = 15.0f
bar.rotation = 15.0f
}
如果你 运行 在那个暂存器中,你会看到 got here
打印在控制台上一次,表明当我们成功更新扩展 属性 两次时,我们跳过了 getSomethingElse()
在第二次调用时,因为新旧旋转相同。
我正在尝试覆盖 Kotlin 中的 View.setRotation() 方法。
由于AndroidKTX已经提供了属性分机"rotation",来电者只需拨打
viewObject.rotation = 90.0f
旋转视图。
但是,我想在用户改变旋转时添加一些额外的操作,比如
override fun setRotation(newRotation: Float) {
if (rotation == newRotation)
return
rotation = newRotation
doSomethingElse()
}
这会因为 Whosebug 错误而崩溃。
所以,我必须添加一些额外的代码来实现目标:
private var _rotation: Float = 0.0f
override fun setRotation(newRotation: Float) {
if (_rotation == newRotation) {
return
}
_rotation = newRotation
updateRotationInternally()
}
private fun updateRotationInternally() {
super.setRotation(_rotation)
doSomethingElse()
}
这行得通,但我想知道是否还有其他更优雅的方法,比如 "override the property extension setter"?
我不同意您实施的一个方面:您的 return
快捷方式。您假设使用现有旋转值调用 setRotation()
无效。如果 View
的官方 Google 版本确实如此,我不会感到惊讶,但据我们所知,这在某些 Oppo 设备 运行 修改后的版本上并不是一个安全的假设Android 8.0。尽量不要假设你没有写的东西的行为。如果你想在新旧旋转相等时跳过doSomethingElse()
,那很好。
我猜你的 setRotation()
函数在 View
的某个子类中。如果是这样,并考虑到我的上述抱怨,这是我能想到的最简单的方法:
class Bar : View() {
override fun setRotation(f: Float) {
val needSomething = getRotation() != f
super.setRotation(f)
if (needSomething) doSomethingElse()
}
fun doSomethingElse() {
println("got here!")
}
}
我的整体测试代码是在 a Kotlin scratchpad 中完成的(在 Android 之外),所以我用一个假的 View
实现和假的 rotation
扩展 [=34] 进行了测试=]:
open class View {
private var r: Float = 0.0f
open fun setRotation(f: Float) {
r = f
}
fun getRotation() = r
}
var View.rotation: Float
get() = getRotation()
set(value) = setRotation(value)
class Bar : View() {
override fun setRotation(f: Float) {
val needSomething = getRotation() != f
super.setRotation(f)
if (needSomething) doSomethingElse()
}
fun doSomethingElse() {
println("got here!")
}
}
fun main() {
val bar = Bar()
bar.rotation = 15.0f
bar.rotation = 15.0f
}
如果你 运行 在那个暂存器中,你会看到 got here
打印在控制台上一次,表明当我们成功更新扩展 属性 两次时,我们跳过了 getSomethingElse()
在第二次调用时,因为新旧旋转相同。