使用 dataBinding 需要在 app module 下面的 build.gradle 文件中进行配置,具体如下:
android {
...
//设置支持dataBinding
dataBinding {
enabled = true
}
...
}
其他简单的细节就不讲了,网上资料很多,这里主要记录一下平时在开发中遇到过的不好解决或者是借助搜索引擎才解决掉的问题。
1、可以在设置属性值的时候,设置默认值
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="bean" type="com.example.NaviBean"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--dataBinding中具体属性值的配置在"@{}"中进行配置-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.name,default=姓名}"/>
</LinearLayout>
</layout>
2、特殊表达式
- 三目运算符简化
//完整写法android:text="@{user.displayName != null ? user.displayName : user.lastName}" //简写android:text="@{user.displayName ?? user.lastName}"
- 空指针异常处理
生成的绑定类会自动检查 null 值以避免 NullPointerException,在表达式 @ {user.name} 中,如果 user 为 null,则为user.name 分配其默认值 null。 如果引用 user.age,其中 age 的类型为 int,则数据绑定使用默认值0。
集合
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="java.util.Map" />
<import type="java.util.List" /> <!--Map-->
<variable
name="map"
type="Map<String,String>" />
<variable
name="key"
type="String" /> <!--List-->
<variable
name="list"
type="List<String>" />
<variable
name="index"
type="int" />
</data>
<!--注意Map和List取值方式-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{map.key}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{list[0]}" />
</LinearLayout>
</layout>
对于 Map 类型的数据可以在表达式 @{} 中使用 map.key 来获取 Map 集合中 key 对应的 value 值,List 类型的数据直接使用索引来取值,此外在 variable 标签中使用到的 < 要进行转义,及使用 < 来代替 <,否则报错如下:
> Error: 与元素类型 "variable" 相关联的 "type" 属性值不能包含 '<' 字符。
- @{} 表达式中使用字符串
如何在 @{} 表达式中使用字符串而不是字符串变量呢,有两种方式,具体如下:
<!--使用单引号-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{map["key"]}' />
<!--使用后引号-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{map[`key`]}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`hhhhh `+bean.name+` sss `}" />
<!--在@{}中可以使用字符串资源-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{@string/app_name}"/>
在 xml 中调用事件方法时,可以在配置当前 View,具体如下:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{(view) -> presenter.onClickEvent(user)}"
android:text="click me 3" />
public class MyPresenter {
public void onClickEvent(View view, User user){}
}
此外,也可以在事件绑定时使用三目运算符,此时可将 void 作为操作符使用,使用方式参考如下:
android:onClick="@{(v) -> v.isVisible() ? presenter.doSomething() : void}"
3、自定义绑定类
从前面可知,默认状态下绑定类名称是由布局文件名称决定,那么如何自定义绑定类呢,在布局文件 data 标签上使用 class 属性指定自定义的绑定类名即可,当然也可以在自定义类名前面添加完成的包路径,参考如下:
<!--自定义绑定类-->
<data
class="com.manu.test.CustomBinding">
<variable name="user" type="com.manu.databindsample.data.User"/>
</data>
在 databinding 中使用 import 关键字导入相关的类,java.lang.* 下面的相关类默认自动导入,如果有相同名字的 View 可以使用使用 alias 来区分,参考如下:
<import type="android.view.View"/>
<import type="com.manu.View" alias="MView"/>
4、include包含布局
使用 variable 关键字定义要在 xml 布局中使用的变量,如果使用了 include 布局,则要使用 bind 绑定 include 包含的布局与主布局使用同样的变量,创建一个 include 包含的布局 test_layout.xml 文件,具体如下:
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="userTest"
type="com.manu.databindsample.data.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`this is include content...`+userTest.getName(),default=user}" />
</LinearLayout>
</layout>
然后,在主布局中引用这个布局,具体如下:
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/resauto">
<data>
<variable
name="user"
type="com.manu.databindsample.data.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--bind绑定变量-->
<include
layout="@layout/test_layout"
bind:userTest="@{user}" />
</LinearLayout>
</layout>
这样通过 bind 就绑定了两个布局中使用到的 User 类型的变量,使得两个布局中使用的变量是同一个变量,此外,databinding 不支持 merge 标签。
5、xml中包含&&符号
& ——> &
代码里:
!TextUtil.isEmpty(viewCtrl.phone) && viewCtrl.phone.length() == 11
xml:
@{!TextUtil.isEmpty(viewCtrl.phone) && viewCtrl.phone.length() == 11 }
文章转载自Android Jetpack组件之DataBinding详解,如果侵权,告之立删!