我如何遍历数据绑定器已知的所有视图?
How can I iterate over all views known to the data binder?
我的布局中有三个 TextInputEditText
视图,用户可以在其中输入特定信息。
单击 Button
,此信息将存储在我的数据库中。
用户点击这个Button
后,我想清除所有TextInputEditText
字段。
现在,我正在通过硬编码来做到这一点:
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
binding.bookTitleEditText.text = null
binding.bookAuthorEditText.text = null
binding.bookPageCountEditText.text = null
}
因为这很糟糕,我想使用动态 for each
循环来识别 binding
已知的所有 TextInputEditText
类型的视图并清除它们的内容:
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
for (view in binding.views) {
if (view is TextInputEditText) {
view.text = null
}
}
很遗憾,没有这样的字段binding.views
。
还有办法实现这个或具有相同属性的东西吗?
到目前为止我尝试了什么
我用过一个BindingAdapter
。在我的 Util
class 中,我创建了一个 EditText
扩展函数 clearText
,注释为 BindingAdapter
和 JvmStatic
:
@JvmStatic
@BindingAdapter("clearText")
fun EditText.clearText(@NotNull shouldClear: Boolean) {
Timber.d("clearText: called")
if (shouldClear) text = null
}
在XML中:
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/book_title_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:imeActionId="100"
android:imeOptions="actionNext"
android:inputType="text"
android:text="@={viewModel.bookTitle}"
app:clearText="@{viewModel.clearAllEditTextFields}"
/>
在我的 ViewModel
class 中,我创建了一个 var clearAllEditTextFields = false
,它在 clearAllEditTextFields()
函数中进行了修改,该函数在我的 ViewModel
中被调用:
...
var clearAllEditTextFields = false
clearAllEditTextFields()
...
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
clearAllEditTextFields = true
}
根据Logcat,我的扩展函数在我的ViewModel
初始化时被调用。但是,当 clearAllEditTextFields()
被调用时,它不会触发对扩展函数的新调用。
不存在用于遍历 binding
对象中的视图的简单 for
循环,您可以尝试以下操作以保持代码的简洁。
作用域函数
binding.apply{
bookTitleEditText.text = null
bookAuthorEditText.text = null
bookPageCountEditText.text = null
}
scope 函数是一个很好的 iff 视图很少,如果视图数量很大,我们最终会得到相当多的 boiler-plate
代码,在这种情况下,我认为 Binding-Adapter
将是一个不错的选择
@BindingAdapter("clear_text")
fun EditText.clearText(shouldClear : Boolean?){
shouldClear?.apply{
if(shouldClear)
text = null
}
}
ViewModel
private val _shouldClear = MutableLiveData<Boolean>()
val shouldClear : LiveData<Boolean>
get() = _shouldClear
fun setClearStatus(status : Boolean){
_shouldClear.value = status
}
//since clearing a text is an event and not state, reset the clear_status once it's done
fun resetClearStatus(){
_shouldClear.value = nul
}
XML
<EditText
......
app:clear_text = "@{yourViewModel.shouldClear}"
...... />
ActivityClass
...
binding.lifecycleOwner = this
...
private fun clearAllEditTextFields() {
yourViewModel.setClearStatus(true)
yourViewModel.resetClearStatus()
}
编辑:
在您的 activity class 中添加 binding.lifecycleOwner = this
并且它用于通过数据绑定观察 LiveData。该视图将在运行时观察文本更改。
我的布局中有三个 TextInputEditText
视图,用户可以在其中输入特定信息。
单击 Button
,此信息将存储在我的数据库中。
用户点击这个Button
后,我想清除所有TextInputEditText
字段。
现在,我正在通过硬编码来做到这一点:
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
binding.bookTitleEditText.text = null
binding.bookAuthorEditText.text = null
binding.bookPageCountEditText.text = null
}
因为这很糟糕,我想使用动态 for each
循环来识别 binding
已知的所有 TextInputEditText
类型的视图并清除它们的内容:
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
for (view in binding.views) {
if (view is TextInputEditText) {
view.text = null
}
}
很遗憾,没有这样的字段binding.views
。
还有办法实现这个或具有相同属性的东西吗?
到目前为止我尝试了什么
我用过一个BindingAdapter
。在我的 Util
class 中,我创建了一个 EditText
扩展函数 clearText
,注释为 BindingAdapter
和 JvmStatic
:
@JvmStatic
@BindingAdapter("clearText")
fun EditText.clearText(@NotNull shouldClear: Boolean) {
Timber.d("clearText: called")
if (shouldClear) text = null
}
在XML中:
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/book_title_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:imeActionId="100"
android:imeOptions="actionNext"
android:inputType="text"
android:text="@={viewModel.bookTitle}"
app:clearText="@{viewModel.clearAllEditTextFields}"
/>
在我的 ViewModel
class 中,我创建了一个 var clearAllEditTextFields = false
,它在 clearAllEditTextFields()
函数中进行了修改,该函数在我的 ViewModel
中被调用:
...
var clearAllEditTextFields = false
clearAllEditTextFields()
...
private fun clearAllEditTextFields() {
Timber.d("clearAllEditTextFields: called")
clearAllEditTextFields = true
}
根据Logcat,我的扩展函数在我的ViewModel
初始化时被调用。但是,当 clearAllEditTextFields()
被调用时,它不会触发对扩展函数的新调用。
不存在用于遍历 binding
对象中的视图的简单 for
循环,您可以尝试以下操作以保持代码的简洁。
作用域函数
binding.apply{
bookTitleEditText.text = null
bookAuthorEditText.text = null
bookPageCountEditText.text = null
}
scope 函数是一个很好的 iff 视图很少,如果视图数量很大,我们最终会得到相当多的 boiler-plate
代码,在这种情况下,我认为 Binding-Adapter
将是一个不错的选择
@BindingAdapter("clear_text")
fun EditText.clearText(shouldClear : Boolean?){
shouldClear?.apply{
if(shouldClear)
text = null
}
}
ViewModel
private val _shouldClear = MutableLiveData<Boolean>()
val shouldClear : LiveData<Boolean>
get() = _shouldClear
fun setClearStatus(status : Boolean){
_shouldClear.value = status
}
//since clearing a text is an event and not state, reset the clear_status once it's done
fun resetClearStatus(){
_shouldClear.value = nul
}
XML
<EditText
......
app:clear_text = "@{yourViewModel.shouldClear}"
...... />
ActivityClass
...
binding.lifecycleOwner = this
...
private fun clearAllEditTextFields() {
yourViewModel.setClearStatus(true)
yourViewModel.resetClearStatus()
}
编辑:
在您的 activity class 中添加 binding.lifecycleOwner = this
并且它用于通过数据绑定观察 LiveData。该视图将在运行时观察文本更改。