Kotlin init块没有执行

问题描述 投票:1回答:2

我创建了一个自定义的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
}

当我运行代码时,我得到了一个N​​PE,constructor首先被执行,然后去setProgress,它因为range为空而崩溃。在init之后,constructor区块没有执行,有什么不对吗?谢谢

android kotlin android-seekbar
2个回答
4
投票

创建属性并在初始化init块中初始化该属性就像在声明时初始化属性一样。只有在调用主构造函数时才会执行init块。您有默认的主构造函数(空构造函数)和自定义辅助构造函数。如果您希望在init块中执行该操作,则必须调用主构造函数。如果你想在每次构造时初始化范围,只需在声明时初始化并删除init块。

var range: Range = Range(0, 100, 1)
    set(value){
        max = value.toSeekbarMaximum()
        field = value
    }

1
投票

问题是你要覆盖range的setter而不是将其支持字段设置为新值。这应该解决它:

var range: Range
    set(value) {
        field = value
        max = value.toSeekbarMaximum()
    }
© www.soinside.com 2019 - 2024. All rights reserved.