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

Jetpack Compose自定义键盘下onValueChange未触发及计算需求

问题解决:GST计算器的onValueChange触发与实时计算实现

一、onValueChange未触发的原因及修复

你的代码中onValueChange未触发,核心问题有两个:

  1. 只读状态的BasicTextField不会触发内部onValueChange:当TextField设为只读(或禁用)时,用户手动输入的事件被拦截,内部的onValueChange回调不会执行。
  2. 状态管理不一致:组件内部维护了textState,但没有和外部传入的inputValue同步,导致外部的回调无法收到更新。

修复后的组件代码

@Composable
fun MyEditTextField(inputValue: String, onValueChange: (String) -> Unit) {
    // 实时计算表达式结果
    val calculationResult by remember(inputValue) {
        derivedStateOf {
            calculateExpression(inputValue)
        }
    }

    Column {
        BasicTextField(
            value = inputValue,
            onValueChange = onValueChange,
            singleLine = true,
            enabled = false // 设为禁用实现只读,仅通过自定义键盘输入
        )
        Text(text = "输入内容: $inputValue")
        Text(text = "计算结果: ${calculationResult ?: "请输入有效算术表达式"}")
    }
}

// 实现简单算术表达式计算(支持+、-、*、/)
private fun calculateExpression(input: String): String? {
    // 匹配"数字+运算符+数字"格式的表达式
    val regex = """(\d+)([+\-*/])(\d+)""".toRegex()
    val match = regex.find(input) ?: return null

    val (num1Str, op, num2Str) = match.destructured
    val num1 = num1Str.toDoubleOrNull() ?: return null
    val num2 = num2Str.toDoubleOrNull() ?: return null

    return when (op) {
        "+" -> formatResult(num1 + num2)
        "-" -> formatResult(num1 - num2)
        "*" -> formatResult(num1 * num2)
        "/" -> if (num2 != 0.0) formatResult(num1 / num2) else "除数不能为0"
        else -> null
    }
}

// 格式化结果:整数显示为整数,小数保留两位
private fun formatResult(value: Double): String {
    return if (value % 1 == 0.0) value.toInt().toString() else "%.2f".format(value)
}

修复后的调用代码

val tvCalculator = remember { mutableStateOf("") }
MyEditTextField(
    inputValue = tvCalculator.value,
    onValueChange = { newValue ->
        tvCalculator.value = newValue
        Log.d("TAG", "inputValue: $newValue")
    }
)

// 自定义键盘的按键点击逻辑示例(比如点击"1")
// Button(onClick = { tvCalculator.value += "1" }) { Text("1") }
// Button(onClick = { tvCalculator.value += "+" }) { Text("+") }

二、实时计算功能实现说明

  • 使用derivedStateOf监听inputValue的变化,每次输入内容更新时自动执行表达式解析与计算,实现类似原生TextWatcher的实时监听效果。
  • 正则表达式匹配简单算术表达式,支持基础四则运算,可根据需求扩展更复杂的表达式解析逻辑(比如多运算符、括号等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:10:39