数据绑定 - MediatorLiveData 未在 Fragment 内触发

Posted

技术标签:

【中文标题】数据绑定 - MediatorLiveData 未在 Fragment 内触发【英文标题】:databinding - MediatorLiveData not firing inside Fragment 【发布时间】:2019-10-11 04:36:27 【问题描述】:

我在片段中遇到 MediatorLiveData 的一些问题。

例如:

我有一个View Model

class InfoPessoalViewModel : NavigationViewModel()

//fields
val nameField = MutableLiveData<String>()

val formMediator = MediatorLiveData<Boolean>()

init 
    formMediator.addSource(nameField)

我通过数据绑定将此名称放入我的 xml 中

<EditText
            android:id="@+id/name"
            android:text="@viewModel.nameField"
            android:layout_
            android:layout_
            android:inputType="textPersonName" />

但是观察者并没有在我的片段内触发。

bindingView.apply 
            lifecycleOwner = this@InfoFragment
            viewModel = viewModel
        

        viewModel.formMediator.observe(this, Observer 
            Log.d("Mediator","Fired!")
        )

有人知道我在这里做错了什么吗?

编辑

我这里改成双向绑定

android:text="@=viewModel.nameField"

但是这些都还没有触发

    viewModel.nameField.observe(this, Observer 
        Log.d("Livedata","Fired!")
    )

    viewModel.formMediator.observe(this, Observer 
        Log.d("Livedata","Fired!")
    )

编辑 2

我正在导入这个 viewModel,如下所示:

  <data>
    <variable
        name="viewModel"
        type="br.com.original.bank.sejaoriginal.steps.infopersonal.InfoPessoalViewModel" />
</data>

在我的片段中绑定视图:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 

    bindingView = DataBindingUtil.inflate(inflater,R.layout.fragment_info_pessoal,container,false)

    return bindingView.root

编辑 3

所以,最初的问题是viewModel = viewModelapply 方法中的引用错误。

但是MediatorLiveData 的问题仍然没有被调用

【问题讨论】:

想要达到什么目的?您想在 nameField 更改或 formMediator 时收到通知吗?如果是这样,您是否真的在 formMediator livedata 中添加了一个新值? @Mordag 我想在 nameField 更改时收到通知。我有一个表单和一个提交按钮,在检查表单的最后一个字段之前需要禁用此按钮。所以,基本上我在听这个中介数据,我用 addSource 把我的所有字段都放在里面 您可能应该考虑为此使用双向绑定。关于收听更改,我建议使用 ObservableField 对象。此类提供属性更改回调。当然,您也可以使用 livedata,但您需要观察每个相关的 livedata 以获得更改。这对你有意义吗? 是的,有一点。但在这种情况下,viewModel.nameField.observe 应该开火吧?但事实并非如此。 这可能是因为您缺少双向绑定。 【参考方案1】:

依次检查这些步骤:

1) 改变这个:

android:text="@viewModel.nameField"

对此(注意附加的等号):

android:text="@=viewModel.nameField"

更多关于 2-way 数据绑定here

2) 检查您是否在 XML 布局中添加了正确的视图模型绑定:

3) 检查代码绑定,将你的绑定代码改成这样:

bindingView.apply 
    lifecycleOwner = this@InfoFragment
    viewModel = this@InfoFragment.viewModel

【讨论】:

如果您使用字符串初始化nameField livedata,您会在视图中看到它吗?因为如果你没有看到它,你肯定是错误配置了数据绑定 当我初始化 nameField 时,观察者正在被解雇,但我没有看到任何东西。 在答案中添加了一个新部分,检查您是否导入了正确的视图模型。如果这是正确的,您需要为您的问题提供更多片段代码 我在答案中添加了我能想到的最后一块。检查您的绑定代码是否引用了正确的视图模型实例,而不是使用 viewModel = viewModel 进行自引用 我已经用这段代码更新了我的问题。我认为我正确地导入了视图模型。关于错误引用的观点很有趣,我将更改我的 viewModel 的名称,以确保安全【参考方案2】:

对我有帮助的一件事,虽然这篇文章没有我遇到的问题:

如果你有一个返回 livedata 的函数,比如 fun myName(): LiveData 返回我的LiveName ,

视图模型绑定不会在 xml 布局中显示值。实时数据必须是变量,而不是函数,例如: val myNameVariable: LiveData = myName()

【讨论】:

以上是关于数据绑定 - MediatorLiveData 未在 Fragment 内触发的主要内容,如果未能解决你的问题,请参考以下文章

MVVM中的MediatorLiveData和MutableLiveData有什么区别

具有多个参数的 MediatorLiveData 或 switchMap 转换

Jetpack之LiveData扩展MediatorLiveData

未解决的参考:将数据绑定导入 MainActivity 时的数据绑定

未找到绑定属性/某些数据未显示

未生成数据绑定类