我正在尝试使用像这样的类对TextInputLayout
使用实时数据和数据绑定:
class MutableLiveDataWithErrorText<T> : MutableLiveData<T>() {
val errorText = MutableLiveData<String>().apply { value = "" }
}
现在,当尝试将其用于xml中的错误文本时,
<layout>
<data>
<!-- ... -->
<variable
name="target"
type="com.my.app.MutableLiveDataWithErrorText<String>" />
</data>
<com.google.android.material.textfield.TextInputLayout
app:errorEnabled="true"
app:errorText="@{target.errorText}">
<!-- ... -->
</com.google.android.material.textfield.TextInputLayout>
</layout>
我收到此错误:
Cannot find getter 'getErrorText' for type String.
我尝试创建BindingAdapter来解决此问题:
@BindingAdapter("errorTextLive")
fun setErrorTextLive(
view: TextInputLayout,
liveDataWithErrorText: MutableLiveDataWithErrorText<String>
) {
if (liveDataWithErrorText.errorText.value.isNullOrEmpty().not()) {
view.error = liveDataWithErrorText.errorText.value
}
}
xml分配更改为:
app:errorTextLive="@{target}"
这使编译成功,但是不再观察到target.errorText
的更改,而是观察target
的更改,仅在errorText
的值更改时更新target
有没有办法让它遵守target.errorText
?
答案 0 :(得分:0)
有没有办法让它遵守target.errorText?
我不这么认为。问题在于,数据绑定库首先在var
内解析target
并发现其类型为target.errorText
,然后它会自动获取MutableLiveData<String>
的值,即类型为String的对象,然后尝试在该String对象上调用getErrorText(),这会导致您看到错误。
我有一个类似的用例,我求助于创建以下类:
target
然后我可以在数据绑定布局中使用所有这些LiveData对象。
答案 1 :(得分:0)
将视图模型作为一组字段而不是一个复合对象传递是错误模式。 如果需要将至少两个变量传递给数据绑定,则需要使用此字段创建视图模型-这样可以帮助您更灵活地进行更改。
例如,您可以像这样定义视图模型:
class SimpleViewModel : ViewModel() {
/**
* Expose MutableLiveData to enable two way data binding
*/
val textData = MutableLiveData<String>().apply { value = "" }
/**
* Expose LiveData for read only fields
*/
val errorText = Transformations.map(textData, ::validateInput)
/**
* Validate input on the fly
*/
private fun validateInput(input: String): String? = when {
input.isBlank() -> "Input is blank!"
else -> null
}
}
在布局方面,它非常接近您的变体形式:
<layout>
<data>
<variable
name="vm"
type="com.example.SimpleViewModel" />
</data>
<android.support.design.widget.TextInputLayout
app:errorEnabled="true"
app:errorText="@{vm.errorText}">
<android.support.design.widget.TextInputEditText
android:text="@={vm.textData}"/>
</android.support.design.widget.TextInputLayout>
</layout>
注意:不必SimpleViewModel
扩展ViewModel
,但它允许您的数据在配置更改后立即使用