Android DataBinding的使用

一、介绍

本文是用来简记DataBinding使用前的配置及一些情况下的使用。

二、环境配置

在项目的要使用DataBinding的module的gradle构建文件里添加如下文件:

cpp 复制代码
android {
    ....
    dataBinding {
        enabled = true    
    }  
}

DataBinding插件将会在你的项目内添加必需提供的以及编译配置依赖。

三、简单使用DataBinding

1、layout文件

DataBinding layout文件与普通布局文件的不同点是:

根标签是 layout ,然后是一个 data 标签和一个ViewGroup标签,此ViewGroup即普通布局的根布局。如下:

java 复制代码
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.zf.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView 
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"/>
       <TextView 
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>

data标签中声明了User类并指定了类对象,在当前layout中可以使用该类。

在layout中的使用方式:@{},如上面的:

java 复制代码
android:text="@{user.firstName}"

2、数据类

在com.zf包下创建一个User类:

java 复制代码
public class User {
   public final String firstName;
   public final String lastName;
   public User(String firstName, String lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
}

3、Binding数据

编译之后会在build\generated\source\apt\debug\项目包名\databinding中生成对应的Binding类。在上述为main_activity.xml,在MainActivity中使用会生成一个MainActivityBinding类,然后调用binding.setUser(user)就可以完成数据的刷新。生成binding的最简单方式是inflating。

java 复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}

四、layout文件

1、variable

在data中可以使用任意数量的variable元素,每个variable元素会在对应的Binding类中生成对应的set、get方法。如下:

java 复制代码
<data>
    <variable
        name="beanHairSideHome"
        type="cn.yanzijia.mine.model.HairSideHomeBean" />

</data>
java 复制代码
public abstract void setBeanHairSideHome(@Nullable cn.yanzijia.mine.model.HairSideHomeBean BeanHairSideHome);
@Nullable
public cn.yanzijia.mine.model.HairSideHomeBean getBeanHairSideHome() {
    return mBeanHairSideHome;
}
2、import

可以在data中添加零个或多个import元素,引入的类可以在layout中直接使用。如下:

java 复制代码
<data>
<import type="android.view.View" />
<variable
    name="beanHairSideHome"
    type="cn.yanzijia.mine.model.HairSideHomeBean" />
</data>

<cn.yanzijia.commonsdk.widget.CustomImageView
    android:id="@+id/mineHairSideFirstImage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@drawable/mine_foreground_ffffff_8dp"
    android:visibility='@{beanHairSideHome.my_hair.img_list.isEmpty()?View.GONE:View.VISIBLE}' />

当类名有冲突的时候可以使用alias设置别名:

cpp 复制代码
<import type="android.view.View"/>
<import type="com.zf.View" alias="myView"/>

在data中使用import导入的类型可以在variable中使用。

cpp 复制代码
<data>
    <import type="com.zf.User"/>
    <import type="java.util.List"/>
    <variable name="userList" type="List<User>"/>
 </data>
3、自定义Binding类名称

默认情况下,生成的Binding类的名称是布局文件去除下划线、(),所有单词首字母大写(被下划线分割的视为一个单词)。

然后再后面加上Binding。被放置在build\generated\source\apt\debug\项目包名\databinding包下。

自定义Binding类名称:

通过data标签后的class属性来进行重命名,如下:

cpp 复制代码
<data class="MineBinding">
    ...
</data>

更换生成的Binding类所在的包:

直接在刚刚的指定的名称前指定包名就可以了。

cpp 复制代码
<data class="com.zf.MineBinding">
    ...
</data>
4、includes

使用如下:

home.xml

cpp 复制代码
<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">
    <data>
        <import type="android.view.View" />
        <variable
            name="fragment"
            type="cn.yanzijia.poster.ui.fragment.HomeTabFragment" />

        <variable
            name="newOrderLeftTime"
            type="String[]" />

        <variable
            name="newOrderCreateTime"
            type="CharSequence" />

        <variable
            name="onlineInfoBean"
            type="cn.yanzijia.poster.model.HomeOnlineInfoBean.ResultBean" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <include
            layout="@layout/poster_layout_home_xm_new_order"
            android:visibility="@{onlineInfoBean.order_new_num>0?View.VISIBLE:View.GONE}"
            app:bean="@{onlineInfoBean}"
            app:fragment="@{fragment}"
            app:newOrderCreateTime="@{newOrderCreateTime}"
            app:newOrderLeftTime="@{newOrderLeftTime}" />
    </LinearLayout>
</layout>

poster_layout_home_xm_new_order.xml文件:

cpp 复制代码
...
<data>

    <variable
        name="bean"
        type="cn.yanzijia.poster.model.HomeOnlineInfoBean.ResultBean" />
    <import type="android.view.View" />

    <import type="android.text.TextUtils" />

    <variable
        name="fragment"
        type="cn.yanzijia.poster.ui.fragment.HomeTabFragment" />

    <variable
        name="newOrderLeftTime"
        type="String[]" />

    <variable
        name="newOrderCreateTime"
        type="CharSequence" />

</data>
...

注意点:

include中添加的传递项在接收的xml文件中必须一一对应。

名称也必须相同。

5、表达式

?? 符号:如果 ?? 左边的对象不为空则取左边的对象,否则取右边的对象。

cpp 复制代码
android:text="@{user.firstName ?? user.lastName}"

三元运算符 ?:

cpp 复制代码
android:text="@{user.firstName != null ? user.firstName : user.lastName}"

\] 符号:用来访问常用集合的值。 ```cpp ... android:text="@{list[index]}" ... android:text="@{sparse[index]}" ... android:text="@{map[key]}" ``` 访问resources资源 正常访问: ```cpp android:src="@{@drawable/poster_ic_fab_back_top}" ``` 使用三元表达式: ```cpp android:src="@{islarge? @drawable/poster_ic_fab_back_top : @drawable/poster_ic_fab_back_top2}" ``` #### 五、Data 对象 上述示例中,Data数据显示在UI上,但是改变Data属性UI不会刷新。DataBinding可以通过绑定使数据变化时UI随之刷新。数据变化的通知方式有三种:Observable objects,ObservableField,observable collection:观察对象、观察字段、观察集合。 ##### 1、Observable objects ViewModel类: ```cpp public class User extends BaseObservable { public String firstName; public String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } @Bindable public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } @Bindable public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } } ``` Acivity类中设置及切换数据: ```cpp private ActivityMainBinding mBinding; private User user; private String[] first = {"张", "周", "李"}; private String[] last = {"倩倩", "花花", "小小"}; private int i = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); user = new User("李","笑笑"); mBinding.setUser(user); } public void changeData(View view) { if (i >= first.length) i = 0; user.setFirstName(first[i]); user.setLastName(last[i]); i++; } ``` activity_main.xml文件: ```cpp

相关推荐
yangshuo12811 小时前
WSA(Windows Subsystem for Android)安装LSPosed和应用教程
android·windows·模拟器·lsposed·windows安卓子系统
ab_dg_dp1 小时前
Android InstalldNativeService::getAppSize源码分析
android
鸿蒙布道师3 小时前
鸿蒙NEXT开发资源工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
V少年3 小时前
深入浅出安卓字节码插装
android
V少年3 小时前
深入浅出Hook
android
V少年3 小时前
深入浅出讲解安卓PMS
android
人生游戏牛马NPC1号5 小时前
学习Android(一)
android·kotlin
_一条咸鱼_5 小时前
深入剖析 Android Hilt 的编译期处理模块(七)
android·kotlin·android jetpack
WWWWW5 小时前
理解VSync-2-app,appsf sf注册回调
android·源码阅读