Android 实时数据和双向数据绑定:未调用自定义setter

Android 实时数据和双向数据绑定:未调用自定义setter,android,data-binding,kotlin,android-databinding,android-livedata,Android,Data Binding,Kotlin,Android Databinding,Android Livedata,我正在使用双向数据绑定使用EditText中设置的字符串从我的ViewModel更新LiveData字符串对象: <android.support.design.widget.TextInputEditText android:id="@+id/writeReviewTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@={viewMode

我正在使用双向数据绑定使用EditText中设置的字符串从我的ViewModel更新LiveData字符串对象:

<android.support.design.widget.TextInputEditText
  android:id="@+id/writeReviewTitle"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="@={viewModel.liveReviewTitle}"
/>

尝试调试此
setter
,但似乎从未调用过!这里发生了什么?感觉有点困惑。文本正在更新,并保存在
ViewModel
中,未调用的只是
setter

当然它从未被调用过,您没有设置新的MutableLiveData,而是在MutableLiveData中设置新的字符串值(可能使用
setValue

但是,如果直接公开MediatorLiveData而不是MutableLiveData,则应该能够截取正在设置的值,并在设置值后执行自定义逻辑

编辑:以下各项应按预期工作:

val liveReviewTitle: MutableLiveData<String> = MutableLiveData()
private val mediator = MediatorLiveData<String>().apply {
    addSource(liveReviewTitle) { value ->
        setValue(value)
        customLogicHere()
    }
}.also { it.observeForever { /* empty */ } }
val liveReviewTitle:MutableLiveData=MutableLiveData()
private val mediator=MediatorLiveData().apply{
addSource(liveReviewTitle){value->
设置值(值)
customLogicHere()
}
}.同时{it.observeforviever{/*empty*/}

@EpicPandaForce对于setter是正确的,它是针对
MutableLiveData
本身,而不是它所持有的值。因此,您的
LiveData
应该是
val
,不需要是
var
,只要您在绑定上设置
LifecycleOwner
,框架就应该做正确的事情。您可以在
LiveData
中添加另一个
Observer
来代替自定义setter来添加自定义逻辑

@EpicPandaForce解决方案是合适的,但在
EditText
中,双向绑定可以以更简单的方式获得。 将属性
PostTextChanged
添加到小部件中,如下所示:

android:afterTextChanged=“@{viewModel::doLogic}”

然后在
ViewModel
类中编写方法:

fun-doLogic(s:可编辑){
//更新Livedata或执行其他逻辑
}

编辑

我错过了重要的文件。更容易(也更主动)的是:


然后在我们的
LifecycleOwner
类中,我们可以根据需要随时更新liveData的值,当然我们可以对注册观察者的更改做出反应。

只需遵循以下示例:@NSimon该示例没有使用库提供的真正的双向数据绑定。开发人员正在创建侦听器并将其自身附加,这是我想要避免的,因为库应该处理这个问题。这是有道理的。我不能直接观察实时数据(比如在构造函数中),因为我需要一个生命周期所有者,对吗?这就是为什么我需要这个调解人?当我从Kotliners conf.回来后,我会写一封信sample@EpicPandaForce我们还能指望承诺的样品吗?我很好奇:)我忘了。但我度假回家后会整理一些东西。明天提醒我,我再也找不到这个问题了XD@Minsky我认为您不需要清理它,因为它只创建了一次,并且随着ViewModel一起消失,但是如果您对此感到不舒服,那么您必须存储对我传入的空lambda的引用,然后在
onCleared()中删除该引用
。我无法从视图模型中观察实时数据,因为它不是生命周期所有者。正如公认的答案所建议的那样,将使用调解人!如果您的内部自定义逻辑不需要了解生命周期,则可以使用
observeforver
。但是
MediatorLiveData
可能是更健壮的方法,具体取决于您的用例。由于中介器也不了解生命周期,因此“永远观察”可能会更容易完成这项工作。我没有设置绑定的生命周期所有者。这把它修好了。非常感谢。这是最简单最正确的答案。我不敢相信我读了这么多文档,他们竟然没有提到这一点。永远是{}天哪!!!我花了两天时间试图知道发生了什么,我的问题是@之后的“=”。谢谢@chitgoksDang!我也这么做了。大家请注意,
“@={viewModel.someLivedata}”
而不仅仅是
“@{viewModel.someLivedata}”
。我使用了双向数据绑定,这种方式工作正常,但是当我在片段中观察同一个LiveData对象时,观察方法会被连续调用,而我不会对EditText做任何更改。这应该发生吗?我不确定。这种行为可能有几个原因。你说的“连续”到底是什么意思?
val liveReviewTitle: MutableLiveData<String> = MutableLiveData()
private val mediator = MediatorLiveData<String>().apply {
    addSource(liveReviewTitle) { value ->
        setValue(value)
        customLogicHere()
    }
}.also { it.observeForever { /* empty */ } }
android:text="@={viewModel.someLivedata}