Android DataBinding和MVVM - 使用相同视图模型为不同条件使用相同的布局文件

Mel*_*Mel 16 android android-layout android-studio android-databinding

我一直在开发一个带有数据绑定和MVVM的应用程序.

我正试图在横向模式下为我的应用程序使用替代布局.我有:

layout/fragment_content.xml
layout-land/fragment_content.xml
Run Code Online (Sandbox Code Playgroud)

两种布局都具有不同外观的相同视图,并从相同的视图模型获取提要,如下所示:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

<data class="MyBinding">

    <variable
        name="viewModel"
        type="com.myapp.package.viewModel.VMFirst"/>

    <variable
        name="controlModel"
        type="com.myapp.package.viewModel.VMSecond"/>
</data>

<DIFFERENT CONTENT HERE>
Run Code Online (Sandbox Code Playgroud)

两种布局都存在所有视图和id.

好吧,问题是,它不编译,错误只是"cannot find symbol method getViewModel"和另一个变量的getter.

到目前为止我尝试了什么:

  1. 使用布局和布局 - 土地文件夹(失败,错误在上面解释)

  2. 使用布局别名使用我在此处找到的布局别名问题199344:数据绑定不适用于布局别名.尝试这种方法时,我没有更改xml文件中的任何内容.这也失败了,错误是Could not write to com.myapp.package.databinding.MyBinding

是否无法data在多个布局文件中使用数据绑定标记?在使用数据绑定时,我应该使用什么来为不同的状态使用不同的布局?谢谢 !

编辑:删除class="MyBinding"没有更改错误.

Mel*_*Mel 7

如果有人搜索这个问题,2 年后我尝试做同样的事情,我发现它现在一切正常。

activity_mainlayout和下创建了一个布局文件layout_sw600dp。这是layout资源下的布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <variable
        name="small_variable"
        type="Integer"/>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/myRoot"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <View
            android:id="@+id/small_square"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:background="@android:color/holo_blue_bright"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

这是layout_sw600dp文件夹下的布局:

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <variable
        name="big_variable"
        type="Long"/>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/myRoot"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <View
            android:id="@+id/big_square"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:background="@android:color/holo_blue_bright"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

两者都有一个视图,但每个视图都有不同的 id:small_squarebig_square

我在手机和平​​板电脑上运行该项目。以下是我的发现:

  • 数据绑定创建一个包含一个实现全部下在不同的布局文件夹中所有同名的布局文件的意见和变量。
  • 存在于所有布局中的视图不可为空,所有其他布局均可为空。在上面的XML的,myRoot不可为空的视图使用从科特林绑定时,而big_squaresmall_square 是可空的视图。无论变量是否存在于所有布局中,它们都是可为空的(这是预期的行为)。
  • 您不能在每个文件中命名不同的绑定类。它必须是相同的(MainBinding在上面的例子中,或者如果你没有定义它LayoutResourceName+Binding默认情况下)。
  • 绑定实现上的视图和变量的名称是驼峰式的。所以我small_variablesmall_squarebinding.smallVariablebinding.smallSquare在代码方面。
  • 使用 Kotlin,您可以只使用像 之类的视图binding.bigSquare?.operation,这很棒,您无需事先检查它是平板电脑还是手机或视图是否为空。
  • 只是一个提示,binding即使不会使用它们所在的布局,您也可以分配字段。您仍然可以binding.smallVariable = 3在代码上说,它会完成分配并保存值。我觉得小心点很好。