I am trying to override View.setRotation() method in Kotlin.
Since AndroidKTX already provided property extension "rotation", caller's can simply call
viewObject.rotation = 90.0f
to rotate the view.
However, I want to add some additional operation when user change the rotation, like
override fun setRotation(newRotation: Float) {
if (rotation == newRotation)
return
rotation = newRotation
doSomethingElse()
}
This will crash because of StackOverflow error.
So, I have to add some additional code to achieve the goal:
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()
}
This works, but I wonder if there is some other more elegant way of doing this, like "override the property extension setter"?
I disagree with one aspect of your implementation: your return
shortcut. You are assuming that calling setRotation()
with the existing rotation value has no effect. It would not surprise me if that is true in the official Google version of View
, but for all we know, that is not a safe assumption on some Oppo device running their modified version of Android 8.0. Try not to assume the behavior of stuff that you didn't write. If you want to skip doSomethingElse()
when the old and new rotations are equal, that's fine.
I am guessing that your setRotation()
functions are in some subclass of View
. If so, and taking my above complaint into account, here's the simplest that I could come up with:
class Bar : View() {
override fun setRotation(f: Float) {
val needSomething = getRotation() != f
super.setRotation(f)
if (needSomething) doSomethingElse()
}
fun doSomethingElse() {
println("got here!")
}
}
My overall test code was done in a Kotlin scratchpad (outside of Android), so I tested with a fake View
implementation and fake rotation
extension property:
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
}
If you run this in that scratchpad, you will see got here
printed on the console once, showing that while we successfully updated the extension property twice, we skipped getSomethingElse()
on the second call, as the old and new rotation were the same.