我正在尝试覆盖 Kotlin 中的 View.setRotation() 方法。
由于 AndroidKTX 已经提供了属性扩展“旋转”,调用者可以简单地调用viewObject.rotation = 90.0f
旋转 View 。
但是,我想在用户更改旋转时添加一些额外的操作,比如
override fun setRotation(newRotation: Float) {
if (rotation == newRotation)
return
rotation = newRotation
doSomethingElse()
}
由于 StackOverflow 错误,这将崩溃。
所以,我必须添加一些额外的代码来实现目标:
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()
}
这行得通,但我想知道是否还有其他更优雅的方法,比如“覆盖属性扩展 setter ”?
最佳答案
我不同意您实现的一个方面:您的 return
捷径。您假设调用 setRotation()
与现有的旋转值没有影响。如果 View
的 Google 官方版本确实如此,我不会感到惊讶。 ,但据我们所知,对于某些运行 Android 8.0 修改版的 Oppo 设备来说,这并不是一个安全的假设。尽量不要假设不是你写的东西的行为。如果你想跳过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
扩展属性: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()
在第二次通话中,因为新旧轮换是相同的。
关于安卓KTX : how to override Kotlin added property extension,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61289326/