在具有数据绑定功能的片段布局中使用Activity ViewModel

时间:2019-08-08 16:05:29

标签: android kotlin data-binding viewmodel androidx

尝试使用数据绑定访问片段布局中的活动viewModel。我不确定我是在做错什么,还是那是行不通的。

MainViewModel具有一个名为_dateString的MutableLiveData属性,以及一个名为getDateString()的函数,该函数返回该属性的LiveData。

private val _dateString = MutableLiveData<String>()
fun getDateString(): LiveData<String> {
    return _dateString
}

然后在Calendar片段的布局中调用该函数。我在布局的数据部分中同时拥有了mainModel和viewModel。 (我删除了大部分布局,以便于阅读)

<layout
    xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
    <import type="android.view.View" />
    <variable
            name="mainModel"
            type="{path}.features.main.MainViewModel" />
    <variable
            name="viewModel"
            type="{path}.features.main.calendar.CalendarViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true">

    <Button
            android:id="@+id/header_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            style="@style/Widget.MaterialComponents.Button"
            android:text="@{mainModel.getDateString()}"/>

</androidx.constraintlayout.widget.ConstraintLayout>

然后在片段本身中,这样绑定变量

binding = FragCalendarBinding.inflate(inflater, container, false).apply {
        viewModel = model
        mainModel = mainModel
        listener = this@CalendarFragment
        lifecycleOwner = this@CalendarFragment
    }

无论出于何种原因,布局都会显示没有值的按钮。即使我更新了_dateString,绑定也不会显示更改后的字符串。

如果将相同的逻辑移到CalendarViewModel中,它将显示并更新。如果我在日历的片段代码中调用getDateString(),它将正确返回该值。

您是否无法将多个视图模型连接到单个布局?还是我在这里做错了。

2 个答案:

答案 0 :(得分:0)

我想我回答这个问题来晚了。无论如何,只需以这种方式编辑XML文件

        <Button
            android:id="@+id/header_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            style="@style/Widget.MaterialComponents.Button"
            android:text="@{mainModel._dateString}"/>

答案 1 :(得分:0)

您可以像这样封装ViewModel数据,以消除对函数调用的需要:

private var _dateString = MutableLiveData<String>()
val dateString : LiveData<String>
    get() = _dateString

这允许您以dateString的形式访问ViewModel之外的值 然后,在您的XML中,您现在可以将文本的值分配给@{mainmodel.dateString},并且只要该值更改,该值就会自动更新