代码之家  ›  专栏  ›  技术社区  ›  Weiyi

Kotlin init块没有执行

  •  1
  • Weiyi  · 技术社区  · 6 年前

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

    constructor 先执行,然后转到 setProgress ,它崩溃是因为 range 为空。这个 init 块在之后没有执行 建造师 ,有什么问题吗?谢谢

    2 回复  |  直到 6 年前
        1
  •  5
  •   Alex Couch    6 年前

    在init块中创建一个属性并初始化该属性就像在声明时初始化属性一样。init块仅在调用主构造函数时执行。您有默认的主构造函数(空构造函数)和自定义的辅助构造函数。如果希望在init块中执行,则必须调用主构造函数。如果希望每次构造时都初始化range,只需在声明时初始化它并去掉init块。

    var range: Range = Range(0, 100, 1)
        set(value){
            max = value.toSeekbarMaximum()
            field = value
        }
    
        2
  •  1
  •   zsmb13    6 年前

    问题是您正在重写 range

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