附加到 TextField 的字符不会在按下退格键时被删除

问题描述

我有一个不能超过 10 个字符的 TextField,并且要求用户以“mm/dd/yyyy”格式输入日期。每当用户输入前 2 个字符时,我附加“/”,当用户输入接下来的 2 个字符时,我再次附加“/”。

为了实现这一点,我做了以下工作:

            var maxCharDate = 10

            TextField(
                value = query2,onValueChange = {
                    if (it.text.length <= maxCharDate) {
                        if (it.text.length == 2 || it.text.length == 5)
                            query2 = TextFieldValue(it.text + "/",selection = TextRange(it.text.length+1))
                        else
                            query2 = it
                    }
                    emailErrorVisible.value = false
                },label = {
                    Text(
                        "Date of Birth (mm/dd/yyyy)",color = colorResource(id = R.color.bright_green),fontFamily = FontFamily(Font(R.font.poppins_regular)),fontSize = with(LocalDensity.current) { dimensionResource(id = R.dimen._12ssp).toSp() })
                },.
                  .
                  .

除了按退格键不会删除附加的“/”之外,其他字符会被删除

如何在按退格键时删除“/”?

解决方法

这是因为您正在检查字符串的长度。当长度为 2 时,插入斜线。因此斜线被删除,然后重新插入。

为什么不创建三个 TextFields 并在它们之间插入斜线作为文本。这种逻辑很难完美。敏锐的用户可以使用它来使您的应用程序崩溃,开发人员也可以插入恶意内容,并利用此漏洞,因为处理逻辑也可能存在漏洞,所以......在我看来,只使用最简单的(和我认为更优雅的)构建方式。

,

/ 正在被删除,但是一旦删除,文本的长度变为 2 或 5。因此它会检查条件,

if (it.text.length == 2 || it.text.length == 5)

由于现在条件为真,/ 再次附加到文本中。所以看起来它根本没有被删除。

解决此问题的一种方法是存储先前的文本长度并检查现在的文本长度是否大于先前的文本长度。

为了实现这一点,在 maxCharDate 下面声明一个变量

var previousTextLength = 0

并将嵌套的 if 条件更改为,

if ((it.text.length == 2 || it.text.length == 5) && it.text.length > previousTextLength)

最后更新 previousTextLength 变量。在 emailErrorVisible.value = false 下方添加

previousTextLength = it.text.length;
,

您可以使用 onValueChange 来定义最大字符数并使用 visualTransformation 来显示您喜欢的格式而不更改 {{1} 中的值}.

TextField

哪里:

val maxChar = 8
TextField(
    singleLine = true,value = text,onValueChange = {
        if (it.length <= maxChar) text = it
    },visualTransformation = DateTransformation()
)

enter image description here