DataBinding允许开发者在布局文件中使用表达式语言,就像在普通代码中一样。表达式语言中可供使用的操作符和关键字如下:
+ - / * %
+
&& ||
& | ^
+ - ! ~
>> >>> <<
== > < >= <=
(Note that <
needs to be escaped as <
)instanceof
()
null
[]
?:
Examples:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
this
super
new
这些操作符,应该不是缺失,而是压根儿就没打算支持,我表示理解,哈哈哈哈。
??
)Null coalescing operator可以翻译为空合并运算符,符号是两个问号??
,该操作符是二元操作符,示例代码如下:
android:text="@{user.displayName ?? user.lastName}"
该操作符返回一个非空的值:**如果左操作数不为空,返回左操作数,否则返回右操作数。**该实例代码类似于:
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
DataBinding生成的binding代码,自动检查值为null的变量,避免空指针异常。例如,在@{user.name}
中,如果user
为null
,user.name
将返回它的默认值null
。如果你的引用是user.age
,age
的类型为int
,此时data binding会使用它的默认值0
。
使用如下语法,你可以在代码中获取资源。
dimens.xml文件:
<resources>
<dimen name="height_little">1dpdimen>
<dimen name="height_large">10dpdimen>
resources>
strings.xml文件:
<resources>
<string name="app_name">MVVMDemostring>
<string name="str_love">%s love %sstring>
resources>
colors.xml文件:
<resources>
<color name="colorPrimaryDark">#00574Bcolor>
resources>
布局文件edit_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:textSize="20dp"
android:textColor="@{@color/colorPrimaryDark}"
android:text='@{@string/str_love("I", "you.")}'
android:padding="@{big ? @dimen/height_little:@dimen/height_large}"/>
LinearLayout>
<data class="EditBinding">
<variable
name="big"
type="boolean" />
data>
layout>
Activity: EditTextActivity.java
public class EditTextActivity extends Activity {
private Employ employ = new Employ("Kevin");
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EditBinding binding = DataBindingUtil.setContentView(this, R.layout.edit_main);
binding.setBig(true);
}
}
以上实例代码就是data binding中常见的使用场景了。
一般的资源,都可以通过这样的代码获取:
android:padding="@{big ? @dimen/height_little:@dimen/height_large}"
Tips:目前Android Studio在输入
@dimen
时并不会提示后续代码,需要你一个个敲出来。这点不是很方便。
对于格式化的字符串,需要使用参数的形式传递值:
<string name="str_love">%s love %sstring>
android:text='@{@string/str_love("I", "you.")}'
参数的数量和占位符%s
的数量一一对应即可。
当布局文件中通过include
标签包含其它布局时,我们需要将当前布局中的变量传递给include
所包含的布局。需要用到ap
p的namespace
, 也就是需要再你的主布局文件中使用:
xmlns:bind="http://schemas.android.com/apk/res-auto"
将变量传递给include包含的子布局时,这样调用
<include
layout="@layout/show_view"
bind:user="@{user}" />
下面是完整代码:
Model文件:Employ.java
public class Employ {
public final ObservableField<String> mName = new ObservableField<>();
public Employ(String name) {
mName.set(name);
}
}
Include包含的子布局文件:show_view.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.superli.mvvmdemo.Employ" />
data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@{user.mName}"
android:textSize="50dp"
android:hint="HHHH"/>
LinearLayout>
layout>
包含Include标签的主布局文件: include_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/show_view"
bind:user="@{user}" />
LinearLayout>
<data class="IncludeBinding">
<variable
name="user"
type="com.superli.mvvmdemo.Employ" />
data>
layout>
Activity: IncludeActivity.java
public class IncludeActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IncludeBinding binding = DataBindingUtil.setContentView(this, R.layout.include_main);
binding.setUser(new Employ("SuperLi"));
}
}
看起来还是很简单的。