我使用双向数据绑定从我的ViewModel更新LiveData String对象,并在EditText中设置字符串:
<android.support.design.widget.TextInputEditText
android:id="@+id/writeReviewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={viewModel.liveReviewTitle}"
/>
因此,根据我的理解,ViewModel
每次在EditText中更改文本时都会更新其liveReviewTitle
属性。我假设这是通过使用TextWatcher或某种由图书馆为我处理的监听机制而发生的。我还认为,当需要更新文本时,它会调用setter
。 似乎并非如此!当文本发生变化时,我需要在我的ViewModel中做更多的事情,因此我为setter
实现了自定义liveReviewTitle
,但没有被调用(我试过调试) )。
这就是ViewModel
类中的样子:
var liveReviewTitle: MutableLiveData<String> = MutableLiveData()
set(value) {
field = value
customLogicHere()
}
尝试调试此setter
但似乎永远不会被调用!这里发生了什么?感觉有点混乱。文本正在更新,并保存在ViewModel
中,只是未调用的setter
。
答案 0 :(得分:5)
当然它从未被调用,你没有设置新的MutableLiveData,你在MutableLiveData中设置一个新的String值(可能带有setValue
)。
但是,如果直接公开MediatorLiveData而不是MutableLiveData,则应该能够拦截正在设置的值并在设置值后执行自定义逻辑。
编辑:以下内容应按预期工作:
val liveReviewTitle: MutableLiveData<String> = MutableLiveData()
private val mediator = MediatorLiveData<String>().apply {
addSource(liveReviewTitle) { value ->
setValue(value)
customLogicHere()
}
}.also { it.observeForever { /* empty */ } }
答案 1 :(得分:2)
@EpicPandaForce对于你的二传手是正确的,它是MutableLiveData
本身而不是它持有的价值。因此,LiveData
应该是val
,不需要var
,只要您在LifecycleOwner
上设置Observer
,框架就应该做正确的事情。捆绑。您可以在LiveData
中添加另一个resources
来代替自定义设置器来添加自定义逻辑。
答案 2 :(得分:0)
@EpicPandaForce解决方案是正确的,但是在EditText
中,可以以更简单的方式获得两种方式的绑定。
将属性afterTextChanged
添加到小部件中,如下所示:
android:afterTextChanged="@{viewModel::doLogic}"
然后在您的ViewModel
类中,只需编写方法:
fun doLogic(s: Editable) {
//update Livedata or do other logic
}
编辑
我错过了重要的文档note。
android:text="@={viewModel.someLivedata}
然后在我们的LifecycleOwner
类中,我们可以在需要时随时更新liveData的值,当然,我们可以对注册观察者的更改做出反应。