如何解决数据绑定 EditText set null 替换为 set empty String 预期行为我是如何尝试的观察到的行为更多观察问题
我创建了一个可以重现此问题的 sample project。
预期行为
我有一个 EditText
。我有一个 TextView
显示有关此 EditText
中输入的错误。我还有一个重置按钮,可以重置 EditText
内的输入。
我想实现以下目标:
- 使用双向数据绑定
- 在用户输入任何内容之前,不应显示任何错误。
- 当用户输入内容并删除它们时,应显示错误
Input cannot be empty
。 - 当用户点击
Reset
时,应清除EditText
内的输入。 - 当用户点击
Reset
时,不应显示错误。
我是如何尝试的
Layout xml:(为了简单起见,我在这里只展示了 EditText
和 TextView
。你可以去示例项目获取完整版)
<EditText
android:id="@+id/et"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_width="0dp"
android:text="@={vm.userInput}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvError"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toBottomOf="@id/et"
app:layout_constraintStart_toStartOf="@id/et"
app:layout_constraintEnd_toEndOf="@id/et"
tools:text="I am some error"
android:text="@{vm.errorText}"
android:textColor="@android:color/holo_red_dark"
android:visibility="@{vm.isErrorVisible() ? View.VISIBLE : View.GONE}" />
视图模型:
val userInput = MutableLiveData<String?>(null)
val errorText = userInput.map { input ->
if (input?.isBlank() == true) {
"This field cannot be empty"
} else {
""
}
}
val isErrorVisible = errorText.map { errorText.value?.isNotBlank() == true }
fun onReset() {
userInput.value = null
}
观察到的行为
1,2,3 实现。 4 无法实现 - 当我点击 Reset
时,显示错误。
更多观察
-
通过调试,我可以观察到在
userInput.value = ""
之后调用了onReset()
。可能是数据绑定库?这也应该是整个问题的原因。 -
如果我在输入已经为空时点击
reset()
,将不会显示错误。即如果输入为空,则上述第 1 点不会发生。
问题
我怎样才能达到 4?
解决方法
当点击重置按钮时,errorText
地图函数会被执行两次 - 立即从 onReset()
的变化开始,我相信,当 TextView 值为更新了。
除了重新考虑整体设计之外,我建议您使用空值和编辑标志来确定 userInput
为空的原因。类似于以下内容:
class MainViewModel : ViewModel() {
private var isInReset = false
val userInput = MutableLiveData<String?>(null)
val errorText = userInput.map { input ->
// We only care to have an opinion if the input field is not null and blank.
// Here we determine why it is blank. Is it because it was reset (OK) or because
// the user deleted all text (not OK).
if (input == null || input.isNotBlank()) {
""
} else if (isInReset) {
isInReset = false
""
} else {
"This field cannot be empty"
}
}
val isErrorVisible = errorText.map { errorText.value?.isNotBlank() == true }
fun onReset() {
isInReset = true
userInput.value = null
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。