You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中实现变量监听?附问题代码求助

Hey there! Let's break down how to implement variable change monitoring in Kotlin, addressing both your initial example and the issue you ran into with the lateinit variable.

1. Fixing Your lateinit Variable Issue

First, let's tackle the problem with your allList setup. lateinit var doesn't play nicely with custom setters directly, since it's designed for variables that get initialized later but can't be null. Instead, we have two better options here:

Option A: Use a nullable variable with a custom setter

If you really need to delay initialization, you can use a nullable list and trigger your callback in the setter:

private var allList: MutableList<MSetting>? = null
    set(value) {
        field = value
        onVariableChange()
    }

private fun onVariableChange() {
    // Safely check the list size even if it's null
    btnDelete.enabled = allList?.size ?: 0 >= 1
}

Later, when you're ready to initialize the list, just assign it like allList = mutableListOf() — this will automatically trigger onVariableChange().

Option B: Initialize with an empty list (simpler for most cases)

If delaying initialization isn't strictly necessary, start with an empty mutable list and use a custom setter to trigger your logic:

private var allList: MutableList<MSetting> = mutableListOf()
    set(value) {
        field = value
        onVariableChange()
    }

private fun onVariableChange() {
    btnDelete.enabled = allList.size >= 1
}

Kotlin's standard library has a built-in delegate specifically for monitoring variable changes — Delegates.observable. It's clean, concise, and handles the change tracking for you:

import kotlin.properties.Delegates

// For your initial example with myList
var myList: List<Int> by Delegates.observable(emptyList()) { _, oldValue, newValue ->
    // You can compare old/new values here if needed
    onVariableChange()
}

// For your allList case
private var allList: MutableList<MSetting> by Delegates.observable(mutableListOf()) { _, _, _ ->
    onVariableChange()
}

fun onVariableChange() {
    btnDelete.enabled = myList.size >= 1 // Or allList.size, depending on which variable you're monitoring
}

Every time you assign a new value to myList or allList, the delegate will trigger the lambda, which calls your onVariableChange() function.

3. Listening to List Internal Changes (Not Just Object Replacement)

Wait a minute — the above methods only trigger when you replace the entire list object. If you need to react when elements are added/removed/modified inside the list (without replacing the list itself), you'll need a custom observable list. Here's how to build one:

class ObservableMutableList<T>(private val delegate: MutableList<T> = mutableListOf()) : MutableList<T> by delegate {
    // Define a callback to trigger when the list changes
    var onListChanged: (() -> Unit)? = null

    // Override all mutable list methods to trigger the callback after modification
    override fun add(element: T): Boolean {
        val result = delegate.add(element)
        onListChanged?.invoke()
        return result
    }

    override fun add(index: Int, element: T) {
        delegate.add(index, element)
        onListChanged?.invoke()
    }

    override fun addAll(elements: Collection<T>): Boolean {
        val result = delegate.addAll(elements)
        onListChanged?.invoke()
        return result
    }

    override fun remove(element: T): Boolean {
        val result = delegate.remove(element)
        onListChanged?.invoke()
        return result
    }

    override fun removeAt(index: Int): T {
        val result = delegate.removeAt(index)
        onListChanged?.invoke()
        return result
    }

    override fun clear() {
        delegate.clear()
        onListChanged?.invoke()
    }

    // Repeat this pattern for other mutable methods like set, removeAll, retainAll, etc.
}

Then use it like this:

private val allList = ObservableMutableList<MSetting>()

init {
    // Attach your callback when initializing
    allList.onListChanged = ::onVariableChange
}

private fun onVariableChange() {
    btnDelete.enabled = allList.size >= 1
}

Now any modification to the list (adding elements, deleting, etc.) will trigger your onVariableChange() function automatically.


内容的提问来源于stack exchange,提问作者HelloCW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:23:17