android 尽管设置了空状态值,但TextField值未设置为空字符串

dgiusagp  于 2023-01-15  发布在  Android
关注(0)|答案(1)|浏览(135)

我的购物清单项目Quantity TextField允许小数点,如果用户键入小数作为第一个字符,如".42",则在下面的代码中将TextField字符串转换为Double时,它会抛出NumberFormatException。为了防止出现异常,我只需检查TextField值是否为"."。如果是,我将Quantity设置为空字符串,并显示一条Toast消息,告诉用户输入一个有效的数量,但它没有将Quantity状态设置为"",并且此时按下十进制键不显示Toast消息。我必须按退格键并再次按小数键才能显示消息。我该如何修复此问题?

    • 购物清单项目模型**
@Parcelize
data class ShoppingListItem(
    val id: Long = 0L,
    val shoppingListId: Long = 0L,
    ...
    val quantity: String = "",
): Parcelable
    • 视图模型**
private val _shoppingListItemState = MutableLiveData(
    savedStateHandle.get<ShoppingListItem>("shoppinglistitem")
        ?: ShoppingListItem()
)

override val shoppingListItemState: LiveData<ShoppingListItem>
    get() = _shoppingListItemState

...

override fun setStateValue(stateToEdit: String, stateValue: Any?) {
 when (stateToEdit) {
      ITEM_QUANTITY_STR -> {
          _shoppingListItemState.value =
          _shoppingListItemState.value!!.copy(quantity = stateValue.toString())
        } 
    }
}
    • 可组合**
CustomOutlinedTextField(
    fieldModifier = Modifier
        .width(150.dp)
        .padding(end = 8.dp)
        .onPreviewKeyEvent {
            if (it.key == Key.Tab && it.nativeKeyEvent.action == ACTION_DOWN) {
                focusManager.moveFocus(FocusDirection.Right)
                true
            } else {
                false
            }
        },
    label = ITEM_QUANTITY_STR,
    inputVal = shoppingListItemState.value!!.quantity,
    isSingleLine = true,
    keyboardOptions = KeyboardOptions.Default.copy(
        capitalization = KeyboardCapitalization.None,
        autoCorrect = false,
        keyboardType = KeyboardType.Decimal,
        imeAction = ImeAction.Next
    ),
    keyboardActions = KeyboardActions(
        onNext = { focusManager.moveFocus(FocusDirection.Right) }
    )
) { value ->
    if(value == ".") {
        Toast.makeText(context, "Please enter a valid quantity", Toast.LENGTH_LONG)
            .show()
        mainViewModel.setStateValue(
            ITEM_QUANTITY_STR,
            ""
        )
    } else {
        if (value.isEmpty()) {
        mainViewModel.setStateValue(
            ITEM_QUANTITY_STR,
            ""
        )
    } else {
            val counter = value.count { it == decimalSeparator }
            if (counter <= 1) {
                if (value.toDouble() <= 999_999.999) {
                    mainViewModel.setStateValue(
                        ITEM_QUANTITY_STR,
                        value
                    )
                }
            }
        }
    }
}
nnsrf1az

nnsrf1az1#

您可以在验证中使用以下内容来防止异常:

value.toDoubleOrNull()

您还可以使用正则表达式将允许的字符限制为十进制数:

val pattern = remember { Regex("^\\d*\\.?\\d*\$") }

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

相关问题