在Kotlin中,如何定义具有延迟默认值的var

for example, a val would be something like this:

val toolbarColor  by lazy {color(R.color.colorPrimary)}

What i want to do is, have a default value for some property (toolbarColor), and i can change that value for anything else. Is it possible?

编辑:这是部分技巧.

var toolbarColor = R.color.colorPrimary
    get() = color(field)
    set(value){
        field = value
    }

Is it possible to ease this by writing

var toolbarColor = color(R.color.colorPrimary)
    set(value){
        field = value
    }

in a way that the default value is computed lazily? At the moment it won't work because color() needs a Context that is only initialized later.

推荐答案

You can create your own delegate method:

private class ColorDelegate<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> {

    private var initializer: (() -> T)? = initializer

    private var value: T? = null

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: initializer!!()
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        this.value = value
    }
}

Declare in some delegate:

object DelegatesExt {
    fun <T> lazyColor(initializer: () -> T): ReadWriteProperty<Any?, T> = ColorDelegate(initializer)
}

使用方法如下:

var toolbarColor by DelegatesExt.lazyColor {
    // you can have access to your current context here.
    // return the default color to be used
    resources.getColor(R.color.your_color)
}

...

override fun onCreate(savedInstanceState: Bundle?) {
    // some fun code
    // toolbarColor at this point will be R.color.your_color
    // but you can set it a new value
    toolbarColor = resources.getColor(R.color.new_color)
    // now toolbarColor has the new value that you provide.
}

I think this could be a cleaner way to do, but I don't know yet (starting with kotlin few days ago). I will take a look and see if this could be done with less code.

Kotlin相关问答推荐

映射中列表类型的Kotlin可空接收器?

为什么我的通用Kotlin函数中的这个转换未经判断?

Kotlin 启动与启动(Dispatchers.Default)

验证构造函数中的值组合

从 Kotlin 调用 Java 时可以为空的规则是什么

Jetpack compose 可滚动表格

T except one class

OnClickListener 未在 ConstraintLayout 上触发

为什么 IntelliJ Idea 无法识别我的 Spek 测试?

Anko 中的水平线性布局

Kotlin 语言是如何用 Kotlin 编写的?

调用单元测试验证伴随对象方法

TextField maxLength - Android Jetpack Compose

@uncheckedVariance 在 Kotlin 中?

未在IntelliJ IDEA上运行临时文件

如何在Kotlin中创建填充空值的通用数组?

Tornadofx - 如何在每个实例上将参数传递给 Fragment

Kotlin 中更好的回调方法是什么?侦听器与高阶函数

Kotlin - 具有私有构造函数的类的工厂函数

在多平台子元素中使用kapt