我可以监控Kotlin中的变量吗?

时间:2018-04-13 00:06:57

标签: kotlin

我希望监视一个变量,当变量发生变化时我会做一些事情,也许就像代码A一样。

如何在Kotlin中编写这些代码?谢谢!

代码A

Private Sub txt_Name_AfterUpdate()

    Dim username As String

    username = UCase(Me.txt_Name.Value)
    Me.txt_Name.Value = username


    If InStr(1, txt_Name.Text, ".", vbTextCompare) > 0 Then
        Me.cb_Shift.SetFocus
    Else
        MsgBox ("Please use the following format:" & vbCrLf & _
               "FirstName.LastName")
        Me.txt_Name.SetFocus
    End If

End Sub

至ice1000

谢谢!但是下面的代码不起作用!当我需要set属性时,我不知道如何初始化allList。

var myList: List<Int>

registerMonitorVar(myList)

fun onVariableChange(){
   if (myList.size>=1){
      btnDelete.enabled=true
   }
}

让人感到害怕:

谢谢!为什么以下代码不正确?

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

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

fun onVariableChange(){
    if (allList.size>=1){

     }
}

Humazed和ice1000

谢谢!当我使用Code 2

时,系统无法监控var allList的变化
 private var allList: MutableList<MSetting>  by Delegates.vetoable(mutableListOf<MSetting>())
    { property, oldValue, newValue ->
        {
            btnRestore.isEnabled=(newValue.size >= 1)
            btnBackup.isEnabled=(newValue.size >= 1)
        }

    }

代码1

 private var allList: MutableList<MSetting>  by Delegates.observable(mutableListOf<MSetting>())
    { property, oldValue, newValue ->
        btnRestore.isEnabled = newValue.size >= 1
    }

代码2

allList=SettingHandler().getListAllSetting().toMutableList() // Observable Work

2 个答案:

答案 0 :(得分:5)

Kotlin observablevetoable非常适合此用例。

否决权正在做你想要的。来自doc:

  

<强>可否决
   返回读/写属性的属性委托   更改时调用指定的回调函数,允许   回调否决修改。

对于您的示例,您可以使用:

var myList: List<Int> by Delegates.vetoable(listOf()) { property, oldValue, newValue ->
    if (newValue.size >= 1)
        true // apply the change to myList
    else
        false // ignore the change. ie. myList stay the same.
}

或简单地说:

var myList: List<Int> by Delegates.vetoable(listOf()) { property, oldValue, newValue ->
    newValue.isNotEmpty()
}

修改后。我在下一个示例中看到observable更合适,因为您似乎希望无论条件如何都要更改列表。

var allList: MutableList<String>  by Delegates.observable(mutableListOf<String>()) { property, oldValue, newValue ->
    btnRestore.isEnabled = newValue.size >= 1
    btnBackup.isEnabled = newValue.size >= 1
}

您的代码无效,因为您添加了不必要的{}并使用了vetoable而未返回true或false。

编辑的答案。它应该得到自己的问题,但无论如何我都会在这里回答。

您可以使用list,当您想要更改列表时,请将其替换为新列表。这会影响性能,因为每次需要添加或删除项目时都会创建新列表。

或者您可以扩展列表类或使用扩展函数来响应添加和删除操作。例如: -

fun main(args: Array<String>) {
    val myList = mutableListOf<Int>()

    myList.addAllAndNotify(listOf(1, 2, 3, 4))
    myList.addAllAndNotify(listOf(1, 2, 88, 9))
}

fun <E> MutableList<E>.addAllAndNotify(elements: Collection<E>) {
    addAll(elements)
    doStuff(this)
}

fun <E> doStuff(list: List<E>) {
    println("list = ${list}")
}

输出:

list = [1, 2, 3, 4]
list = [1, 2, 3, 4, 1, 2, 88, 9]  

最后,你可以看一下这个带有ObservableList的好lib,如果你需要你更好地使用它而不是自己编写它。

答案 1 :(得分:2)

您可以覆盖和设置器。

var myList: List<Int> // maybe here's a missing initialization 
  set(value) {
    field = value
    onVariableChange()
  }

fun onVariableChange() {
   if (myList.size >= 1) {
      btnDelete.enabled = true
   }
}

这样,如果您执行myList = blabla,则会调用onVariableChange

编辑,为什么不

private var allList = mutableListOf<String>()
    set(value) {
        field = value
        onVariableChange()
    }


fun onVariableChange() {
    if (allList.size >= 1) {
    }
}

此代码有效吗?

对于评论,您可以使用:

private var allList = listOf<String>()
    set(value) {
        field = value
        onVariableChange()
    }