Использование пользовательского сеттера для ленивого делегата - PullRequest
0 голосов
/ 22 января 2019

У меня много повторяющегося кода, и, поскольку я довольно новичок в Kotlin, я хочу учиться и стараться использовать его как можно больше.У меня есть много лениво объявленных MutableLiveData<Int> свойств, и где-то внизу кода я проверяю каждое из них, чтобы убедиться, что значение живых данных никогда не опустится ниже 0. Я думал, что использование делегатов Kotlin будет работать, но я чувствую, что я вa lost.

Вот фрагмент моего объявления (по умолчанию значение равно 0).

    private val count: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>().also { it.value = 0 }
    }

Вот фрагмент некоторых onClickListeners.

    btn_decrement.setOnClickListener {
        count.value?.run {
            if (this > 0) {
                count.value = this - 1
            }
        }
    }

Я хочусделать что-то вроде следующего:

    private val d4Count: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>().also { it.value = 0 }
    }
    set(value) {
        if (field.value?.toInt() - value < 0) field.value = 0 else field.value -= value
    }

Но Android Studio выдаёт мне 2 ошибки:

  1. Свойство 'val' не может иметь установщика.Это имеет смысл, но есть ли способ сохранить неизменным count, но изменить установщик MutableLiveData<Int> на что-то похожее на мою попытку?

  2. Делегированное свойство не может иметь методы доступа с нереализации по умолчанию.Я действительно не знаю, что это значит, но я предполагаю, что это ключ к тому, чтобы я достиг того, чего хочу.

Как мне поступить, или я смотрю наэто неправильно?Есть ли лучший способ сделать то, что я хочу?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Использование дополнительных свойств может вам помочь:

class SomeClass {
    var count = 0
        set(value) { 
            if (field - value < 0) field = 0 else field -= value
            _count.value = field
        }

    private val _count: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>().also { it.value = 0 }
    }
}

// Using additional property
val s = SomeClass()
s.count = 5 // this will set value to `count` and `_count` properties depending on the condition in the setter of `count` property.
0 голосов
/ 22 января 2019

Во-первых, это не то, как вы используете MutableLiveData. Вы устанавливаете значение с помощью setValue (в главном потоке or postValue` (в любом потоке).

val d4Count = MutableLiveData<Int>()

status.value = 4
status.postValue(4)

Если вы хотите изменить сеттер MutableLiveData, вы можете либо расширить MutableLiveData (1), либо создать метод сеттера (2).

(1)

class CustomIntLiveData: MutableLiveData<Int>() {
    override fun setValue(value: Int?) {
        super.setValue(processValue(value))
    }

    override fun postValue(value: Int?) {
        super.postValue(processValue(value))
    }

    private fun processValue(value: Int?) : Int {
        val currentValue = this.value
        return if (currentValue == null || value == null || currentValue - value < 0) {
            0
        } else {
            currentValue - value
        }
    }
}

(2)

fun setCount(value: Int?) {
    val currentValue = d4Count.value

    if (currentValue == null || value == null || currentValue - value < 0) {
        d4Count.value = 0
    } else {
        d4Count.value = currentValue - value
    }
}

Делегированное свойство не может иметь средства доступа с реализациями не по умолчанию. Я действительно не знаю, что это значит, но я предполагаю, что это ключ к тому, чтобы я достиг того, чего хочу.

Это означает, что вы не можете использовать set, если вы используете by.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...