Jetpack Compose中如何限制TextField中只能输入数字?

10
我希望在文本字段中只输入数字。我尝试了这个stackoverflow的逻辑来限制字母和特殊字符,但是当我按下键盘上的点时,它会崩溃。 错误
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(
                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,
            )

你只需要数字还是数字字符也可以? - Gabriele Mariotti
@GabrieleMariotti 我想要像12345678这样的数字...我不知道什么是数字和数码。数字和数码有什么区别? - Kotlin Learner
我的错,抱歉。带小数的数字。 - Gabriele Mariotti
我不需要小数,只需要整数。 - Kotlin Learner
5个回答

21

你可以使用正则表达式模式。

类似于:

val pattern = remember { Regex("^\\d+\$") }

TextField(
    value = text,
    onValueChange = {
        if (it.isEmpty() || it.matches(pattern)) {
            text = it
        }
    },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)

1
当你只有一个文本时,有一个问题就是你无法使用退格键删除数字。 - Kotlin Learner
1
@vivekmodi 答案已更新。 - Gabriele Mariotti
1
可以修改正则表达式为零个或多个数字 Regex("^\\d*\$"),并且可以从if条件中删除 it.isEmpty() - elementstyle
实际上,在使用正则表达式进行控制后,无需添加键盘选项,因为我们只在输入数字时进行更改。对吧? - undefined

4
您可以像这样过滤字符串:
TextField(
    value = text,
    onValueChange = {
        if (it.isEmpty()) {
            text = it.filter { symbol ->
                symbol.isDigit()
            }
        }
    },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)

我只想输入正整数,这是正确的方法,谢谢。 - undefined

4
这是我为了实现这个目标所做的事情:
TextField(
    value = text,
    onValueChange = { if (it.isDigitsOnly()) text = it },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)

3

如果你想只显示数字键盘,只需这样操作:

TextField(
     value = textState,
     onValueChange = { text ->
         textState = text
     },
     keyboardOptions = KeyboardOptions.Default.copy(
         keyboardType = KeyboardType.NumberPassword
     ),
     visualTransformation = VisualTransformation.None
)

1
你可以将文本字段限制为仅包含数字
var amount by remember { mutableStateOf("") }    
TextField(value = amount, onValueChange = {if (it.isDigitsOnly()) amount = it}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接