Блок инициализации Kotlin не выполнен - PullRequest
0 голосов
/ 15 сентября 2018

Я создал пользовательский SeekBar, который расширяет android.widget.Seekbar:

data class Range(val min: Int, val max: Int, private val defaultIncrement: Int) {
    val increment = if ((max - min) < defaultIncrement) 1 else defaultIncrement
}

internal fun Range.toSeekbarMaximum(): Int = (max - min) / increment

class RangeSeekBar: SeekBar {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    init {
        range = Range(0, 100, 1)
    }

    var range: Range
        set(value) {
            max = value.toSeekbarMaximum()
        }

    override fun setProgress(progress: Int) = super.setProgress((progress - range.min) / range.increment)

    override fun getProgress(): Int = range.min + super.getProgress() * range.increment
}

Я получил NPE, когда запускаю коды, сначала выполняется constructor, а затем переходит к setProgress, он завис, потому что range равен нулю. Блок init не выполняется после constructor, что-то не так? Спасибо

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Создание свойства и инициализация этого свойства в блоке инициализации, аналогично тому, как вы его используете, аналогичны инициализации свойства при объявлении.Блок init выполняется только тогда, когда вызывается основной конструктор.У вас есть основной конструктор по умолчанию (пустой конструктор) и пользовательские вторичные конструкторы.Если вы хотите, чтобы это выполнялось в блоке init, вам придется вызвать первичный конструктор.Если вы хотите, чтобы range был init'd при создании каждый раз, просто инициализируйте его при объявлении и избавьтесь от блока init.

var range: Range = Range(0, 100, 1)
    set(value){
        max = value.toSeekbarMaximum()
        field = value
    }
0 голосов
/ 15 сентября 2018

Проблема в том, что вы переопределяете установщик range и не устанавливаете в его поле поддержки новые значения. Это должно исправить это:

var range: Range
    set(value) {
        field = value
        max = value.toSeekbarMaximum()
    }
...