【问题标题】:databinding - MediatorLiveData not firing inside Fragment数据绑定 - MediatorLiveData 未在 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_width="match_parent"
            android:layout_height="wrap_content"
            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 应该开火吧?但事实并非如此。
  • 这可能是因为您缺少双向绑定。

标签: android kotlin android-databinding android-livedata


【解决方案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()

【讨论】:

    猜你喜欢
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 2018-01-05
    • 2013-07-31
    相关资源
    最近更新 更多