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

Jetpack Compose限制TextField仅输入数字时点击小数点崩溃

问题:Jetpack Compose TextField限制数字输入时点击小数点崩溃

我想在Jetpack Compose的TextField中仅允许输入数字,参考相关逻辑限制字母和特殊字符后,点击键盘上的小数点时应用直接崩溃。


错误日志

2022-08-18 09:47:13.966 8050-8050/com.abc.app.dev E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.abc.app.dev, PID: 8050
    java.lang.NumberFormatException: For input string: "."
        at java.lang.Integer.parseInt(Integer.java:733)
        at java.lang.Integer.parseInt(Integer.java:865)
        at com.abc.app.yo.composable.InputKt$InputWithUnitContainer$1$1$1$1.invoke(Input.kt:187)
        at com.abc.app.yo.composable.InputKt$InputWithUnitContainer$1$1$1$1.invoke(Input.kt:186)
        at androidx.compose.foundation.text.BasicTextFieldKt$BasicTextField$7$1.invoke(BasicTextField.kt:266)
        at androidx.compose.foundation.text.BasicTextFieldKt$BasicTextField$7$1.invoke(BasicTextField.kt:264)
        at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$onValueChangeWrapper$1.invoke(CoreTextField.kt:241)
        at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$onValueChangeWrapper$1.invoke(CoreTextField.kt:236)
        at androidx.compose.foundation.text.TextFieldDelegate$Companion.onEditCommand(TextFieldDelegate.kt:198)
        at androidx.compose.foundation.text.TextFieldDelegate$Companion.access$onEditCommand(TextFieldDelegate.kt:90)
        at androidx.compose.foundation.text.TextFieldDelegate$Companion$restartInput$1.invoke(TextFieldDelegate.kt:246)
        at androidx.compose.foundation.text.TextFieldDelegate$Companion$restartInput$1.invoke(TextFieldDelegate.kt:243)
        at androidx.compose.ui.text.input.TextInputServiceAndroid$createInputConnection$1.onEditCommands(TextInputServiceAndroid.android.kt:111)
        at androidx.compose.ui.text.input.RecordingInputConnection.endBatchEditInternal(RecordingInputConnection.android.kt:162)
        at androidx.compose.ui.text.input.RecordingInputConnection.addEditCommandWithBatch(RecordingInputConnection.android.kt:136)
        at androidx.compose.ui.text.input.RecordingInputConnection.commitText(RecordingInputConnection.android.kt:181)
        at com.android.internal.inputmethod.RemoteInputConnectionImpl.lambda$commitText$16$com-android-internal-inputmethod-RemoteInputConnectionImpl(RemoteInputConnectionImpl.java:569)
        at com.android.internal.inputmethod.RemoteInputConnectionImpl$$ExternalSyntheticLambda34.run(Unknown Source:8)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

相关代码
传递的参数:

appendTextFieldValue: (TextFieldValue) -> Unit,

TextField实现:

TextField(
    value = textFieldValue,
    singleLine = true,
    onValueChange = {
        if (it.text.length <= maxLength && it.text.toInt() <= maxLength) {
            appendTextFieldValue(it)
        }
        onIsErrorChange(false)
    },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
    isError = isError,
)

解决方案

崩溃原因:点击小数点后输入框内容变为.,此时调用it.text.toInt()会抛出NumberFormatException,因为.无法转换为整数。

修复方案如下:

方案1:严格过滤非数字字符

直接过滤输入中的非数字内容,从根源避免无效输入:

onValueChange = { newVal ->
    val filteredText = newVal.text.filter { it.isDigit() }
    if (filteredText.length <= maxLength) {
        val numericValue = if (filteredText.isEmpty()) 0 else filteredText.toInt()
        if (numericValue <= maxLength) {
            appendTextFieldValue(newVal.copy(text = filteredText))
        }
    }
    onIsErrorChange(false)
}

方案2:安全转换整数

通过runCatching捕获转换异常,仅在转换成功时更新输入框:

onValueChange = { newVal ->
    val inputText = newVal.text
    if (inputText.length <= maxLength) {
        runCatching { inputText.toInt() }
            .onSuccess { num ->
                if (num <= maxLength) {
                    appendTextFieldValue(newVal)
                }
            }
    }
    onIsErrorChange(false)
}

如果需要支持小数输入,需将toInt()改为toDouble(),同时把keyboardType改为KeyboardType.Decimal;若仅需整数输入,优先选择方案1,体验更流畅。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:18:07