android - 如何使用 RxTextView (RxBinding) 检测 EditText 何时为空
问题描述
我正在对EditText
. CharSequence
如果它为空或不以"https://"开头,我希望它无效。我也在使用RxBinding,特别是RxTextView
. 问题是,当剩下一个字符时,然后我将其删除,在地图运算符中没有留下任何字符时CharSequence
不会触发发射。换句话说,我希望我的地图运算符在 EditText 为空时返回 false。我开始认为这可能是不可能的,因为我正在这样做。什么是替代方案?
这是我的 Observable / Disposable:
val systemIdDisposable = RxTextView.textChanges(binding.etSystemId)
.skipInitialValue()
.map { charSeq ->
if (charSeq.isEmpty()) {
false
} else {
viewModel.isSystemIdValid(charSeq.toString())
}
}
.subscribe { isValid ->
if (!isValid) {
binding.systemIdTextInputLayout.isErrorEnabled = true
binding.systemIdTextInputLayout.error = viewModel.authErrorFields.value?.systemId
} else {
binding.systemIdTextInputLayout.isErrorEnabled = false
binding.systemIdTextInputLayout.error = viewModel.authErrorFields.value?.systemId
}
}
这是ViewModel
我传递CharSequence
给验证的函数:
fun isSystemIdValid(systemId: String?): Boolean {
return if (systemId != null && systemId.isNotEmpty()) {
_authErrors.value?.systemId = null
true
} else {
_authErrors.value?.systemId =
getApplication<Application>().resources.getString(R.string.field_empty_error)
false
}
}
解决方案
睡了之后,我就明白了。
我RxTextView.textChanges
改为RxTextView.textChangeEvents
. 这允许我查询CharSequence
的文本值(使用text()
提供的方法textChangeEvents
),即使它是空的。由于其他一些变化(与我在这个问题中提出的问题并不真正相关),我也能够减少一些条件代码。我只是把它放在那里,以防有人遇到这个并对这些变化感到好奇。要点是您可以使用RxTextView.textChangeEvents
.
这是我的新观察员:
val systemIdDisposable = RxTextView.textChangeEvents(binding.etSystemId)
.skipInitialValue()
.map { charSeq -> viewModel.isSystemIdValid(charSeq.text().toString()) }
.subscribe {
binding.systemIdTextInputLayout.error = viewModel.authErrors.value?.systemId
}
这是我在 ViewModel 中的验证代码:
fun isSystemIdValid(systemId: String?): Boolean {
val auth = _authErrors.value
return if (systemId != null && systemId.isNotEmpty()) {
auth?.systemId = null
_authErrors.value = auth
true
} else {
auth?.systemId =
getApplication<Application>().resources.getString(R.string.field_empty_error)
_authErrors.value = auth
false
}
}
Lastly, if anyone is curious about how I'm using my LiveData / MutableLiveData objects; I create a private MutableLiveData object and only expose an immutable LiveData object that returns the values of the first object. I do this for better encapsulation / data hiding. Here is an example:
private val _authErrors: MutableLiveData<AuthErrorFields> by lazy {
MutableLiveData<AuthErrorFields>()
}
val authErrors: LiveData<AuthErrorFields>
get() { return _authErrors }
Hope this helps someone!
推荐阅读
- python - 如何将numpy数组的某些索引的值更改为0?
- sql - 使用主键获取 Oracle 元数据
- java - Java:如何用分隔符值替换字符串中的空格和\r?
- c# - 在 .csproj 类库中自动嵌套文件 (DependentUpon)
- agora.io - Agora Unity 插件无法将视频流式传输给其他用户。在日志中,出现“无法初始化编码器”错误
- javascript - 在 TypeScript 中解构 React 钩子数组时,此表达式不可调用
- c++ - Clangd - 如何在没有`compile_commands.json`时设置要使用的默认标志?
- javascript - Javascript 全局变量与 HTML 数据属性
- c - 函数泄漏内存尚未释放
- python - pyinstaller raspberry pi 编译,如何从命令行执行程序