问题描述
我一直在开发具有数据绑定功能的应用程序; MVVM.
I've been developing an app with data binding & MVVM.
我正在尝试在横向模式下为我的应用程序使用其他布局.我有:
I'm trying to use an alternative layout for my app on landscape mode. I have:
layout/fragment_content.xml
layout-land/fragment_content.xml
这两种布局都具有外观不同的相同视图,并从相同的视图模型获取供稿,如下所示:
Both layouts have same views with different look, and get feeds from same view models, like this:
<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>
所有视图和ID都存在于两种布局中.
All the views and id's exist in both layouts.
好吧,问题是,它无法编译,错误仅是"cannot find symbol method getViewModel"
,而另一个变量是getter.
Well, problem is, it doesn't compile, error is simply "cannot find symbol method getViewModel"
and getter for the other variable.
到目前为止我尝试过的事情:
What I tried so far:
-
使用layout和layout-land文件夹(失败,上面已解释错误)
Using layout and layout-land folders ( Failed, error is explained above )
使用布局别名使用布局别名我在这里找到.尝试此方法时,我没有更改xml文件中的任何内容.这也失败了,错误是Could not write to com.myapp.package.databinding.MyBinding
Using layout aliases Use Layout Aliases which I found here Issue 199344: Data binding does not work with layout aliases. I didn't change anything in xml files while trying this approach. This also failed, error is Could not write to com.myapp.package.databinding.MyBinding
是否可以在多个布局文件中使用数据绑定data
标签?在使用数据绑定时,应该使用什么来针对不同的状态使用不同的布局?谢谢!
Is it not possible to use data binding data
tag in multiple layout files ? What should I use to use different layouts for different states while using data binding ? Thanks !
删除class="MyBinding"
不会更改错误.
推荐答案
如果有人搜索了这个问题,两年后我尝试做同样的事情,发现现在一切正常.
If anyone searches for this question, after 2 years I tried to do the same, and I saw it's working all fine now.
我在layout
和layout_sw600dp
下创建了布局文件activity_main
.这是layout
资源下的布局:
I created a layout file activity_main
under layout
and layout_sw600dp
. Here's the layout under layout
resources:
<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>
这是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>
两者都有一个视图,但每个视图都有不同的ID:small_square
和big_square
.
Both has a view but it has different id in each: small_square
and big_square
.
我在电话&上运行该项目药片.这是我的发现:
I run the project on phone & tablet. Here are my findings:
- DataBinding创建一个实现,该实现在不同布局文件夹中相同名称的所有布局文件下包含 ALL 视图和变量.
- 所有布局中的视图均不可为空,其他所有视图均可为空.在上述XML中,使用来自Kotlin的绑定时,
myRoot
是不能为空的视图,而big_square
和small_square
是可以为空的视图.变量是否为空,无论它们是否存在于所有布局中(这是预期行为). - 您不能在每个文件中命名不同的绑定类.它必须相同(在上面的示例中为
MainBinding
,或者默认情况下未定义为LayoutResourceName
+Binding
). - 关于绑定实现的视图和变量的名称均为驼峰式.所以我的
small_variable
&small_square
在代码方面是binding.smallVariable
和binding.smallSquare
. - 使用Kotlin,您可以仅使用
binding.bigSquare?.operation
之类的视图,这很好,您无需事先检查它是平板电脑还是手机,或者视图是否为空. - 提示,即使不使用布局,也可以分配
binding
字段.您仍然可以在代码上说binding.smallVariable = 3
,它将完成分配并保存值.我认为要小心一点.
- DataBinding creates an implementation that contains ALL views and variables under all layout files of same name in different layout folders.
- Views that exists in all layouts are not nullable, all others are nullable. In above XML's,
myRoot
is not a nullable view when using binding from Kotlin, whilebig_square
andsmall_square
are nullable views. Variables are nullable whether or not they exists in all layouts ( which is expected behaviour ). - You cannot name binding classes different in each file. It has to be same (
MainBinding
in above examples, or if you don't define itLayoutResourceName
+Binding
by default ). - Names for views and variables on binding implementation are camel case. So my
small_variable
&small_square
wasbinding.smallVariable
andbinding.smallSquare
on code side. - With Kotlin, you can just use views like
binding.bigSquare?.operation
, which is great that you don't need to check if it's tablet or phone or view is null or not beforehand. - Just a tip, you can assign
binding
fields even if layout that they are in won't be used. You can still saybinding.smallVariable = 3
on code and it'll do the assignment and save the value. I think it's good to be careful.
这篇关于Android数据绑定和MVVM-对不同布局文件夹中的布局文件使用相同的名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!