我正在使用带有 XML 数据绑定的 M3 TextField。我想将输入发送到 ViewModel,如果有效,文本字段的文本应等于此输入,否则 TextField 的文本不应更改。
这里是XML代码:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/outlinedTextField"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="Text"
app:layout_constraintEnd_toEndOf="@+id/textView"
app:layout_constraintStart_toStartOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:suffixText="..."
app:suffixTextColor="?colorOutline">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.text}"
android:onTextChanged="@{(text, start, before, count) -> viewModel.updateText(text)}"
android:inputType="numberDecimal"/>
</com.google.android.material.textfield.TextInputLayout>
这是视图模型:
private val _text = MutableStateFlow("")
val text: StateFlow<String> = _text.asStateFlow()
fun updateText(text: CharSequence) {
val regex = "..." // -> A regex for validation
val isValid = Pattern.compile(regex).matcher(text).find()
if (isValid) _text.value = text.toString()
}
当我运行此代码时,viewModel 中的文本值在对正则表达式无效时不会更改。但是,即使文本字段的输入对正则表达式无效,它也会发生变化。
我该如何解决这个问题?
更新您的 ViewModel 代码以存储先前的有效输入文本,并且仅在新输入有效时才更新文本字段的文本。否则,恢复以前的有效输入文本。
private val _text = MutableStateFlow("")
private var previousValidText = ""
val text: StateFlow<String> = _text.asStateFlow()
fun updateText(text: CharSequence) {
val regex = "..." // A regex for validation
val isValid = Pattern.compile(regex).matcher(text).find()
if (isValid) {
_text.value = text.toString()
previousValidText = text.toString()
} else {
_text.value = previousValidText
}
}
并在您的 XML 代码中,更新 android:onTextChanged 属性以使用 lambda 表达式并使用新的文本值调用 updateText 方法。
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.text}"
android:onTextChanged="@{(text, start, before, count) -> viewModel.updateText(text)}"
android:inputType="numberDecimal" />