一点 Kotlin 的小感想


Delegated properties 加上 remember 函数, 可以把 Composable 中的状态变量变成类似 C 中的 static 局部变量, 比如这里:

@Composable
fun EditNumberField() {
   var amountInput by remember { mutableStateOf("") }
   TextField(
       value = amountInput,
       onValueChange = { amountInput = it },
   )
}

每次 TextField 中的内容被修改, amountInput 就会被修改, 然后被记住. 这样一来, 在 recomposition 的时候 (即重新调用 EditNumberField() 时), amountInput 不会变成初始值 (空字符), 而是会记住上次的结果.

大量使用 lambda 函数, 并且用它来捕获变量. 如 State hoisting, 它将上面 EditNumberField() 中的状态变量 amountInput 提升到调用它的函数中 (TipTimeScreen()), 从而把 stateful Composable 变成 stateless 的, 也就是, 主要会增加两个参数:

这个 onValueChange 是调用点传入的 lambda 函数, 它可以捕获位于调用点函数中, 被提升了的 amountInput. 最后的两个函数如下:

@Composable
fun TipTimeScreen() {
    // State hoisting 允许本来 EditNumberField 私有的状态 amountInput
    // 被其他 Composable 共享, 从而计算 tip 的值
    var amountInput by remember { mutableStateOf("") }
    val amount = amountInput.toDoubleOrNull() ?: 0.0
    val tip = calculateTip(amount)

    Column() {
        EditNumberField(
            value = amountInput,
            onValueChange = { amountInput = it } // lambda 函数捕获 amountInput
        )
        // 展示计算出的小费
        Text(text = stringResource(R.string.tip_amount, tip))
    }
}

@Composable
fun EditNumberField(            // 用于获取输入金额
       value: String,
       onValueChange: (String) -> Unit
   ) {
   TextField(
       value = value,
       onValueChange = onValueChange,
   )
}

Authorthebesttv
Created2023-03-25 21:34
Modified2023-03-25 23:31
Generated2024-06-11 02:39
VersionEmacs 29.3 (Org mode 9.6.15)
Raw2023-03-25.org