Android KTX: как переопределить Kotlin добавлено расширение свойства - PullRequest
1 голос
/ 18 апреля 2020

Я пытаюсь переопределить метод View.setRotation () в Kotlin.

Поскольку AndroidKTX уже предоставил расширение свойства "вращение", вызывающие могут просто вызывать

viewObject.rotation = 90.0f

для поворота вида.

Однако я хочу добавить некоторые дополнительные операции, когда пользователь изменяет вращение, например

override fun setRotation(newRotation: Float) {
    if (rotation == newRotation)
        return
    rotation = newRotation
    doSomethingElse()
}

Это приведет к sh из-за ошибки 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()
    }

Это работает, но мне интересно, есть ли какой-нибудь другой более элегантный способ сделать это, например " переопределить установщик расширения свойства "?

1 Ответ

2 голосов
/ 18 апреля 2020

Я не согласен с одним аспектом вашей реализации: вашим return ярлыком. Вы предполагаете, что вызов setRotation() с существующим значением поворота не имеет никакого эффекта. Меня не удивит, если это так в официальной версии Google View, но, насколько нам известно, это не является безопасным допущением на некоторых устройствах 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 блокноте (снаружи из 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, напечатанный на консоль один раз, показывая, что, хотя мы успешно обновили свойство extension дважды, мы пропустили getSomethingElse() при втором вызове, поскольку старая и новая ротация были одинаковыми.

...