实时数据和双向数据绑定:未调用自定义设置器

时间:2018-06-15 13:12:03

标签: android data-binding kotlin android-databinding android-livedata

我使用双向数据绑定从我的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

3 个答案:

答案 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的值,当然,我们可以对注册观察者的更改做出反应。