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

相关推荐
雨白3 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹5 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空6 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭7 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日8 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安8 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑8 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟12 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡13 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0013 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体