Android-Jetpack

Jetpack系列组件--dataBinding从相遇到相知

2020-02-14  本文已影响0人  蓅哖伊人为谁笑
一、什么是dataBinding
二、 dataBinding的优势
三、如何引入ViewModel

需要在使用dataBinding的模块的build.gradle文件中添加dataBinding配置,
如下所示,

每个使用dataBinding的模块都应该在build.gradle中添加如下配置

 android {
  ...
  dataBinding {
      enabled = true
  }
}

四、dataBinding如何使用
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    <data>
        <variable
            name="user"
            type="com.mooc.ppjoke.model.User" />
        <import type="com.mooc.ppjoke.user.UserManager"></import>
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout>
        <TextView
            android:id="@+id/tvName"
            android:layout_width="200dp"  //不能使用dataBinding动态绑定
            android:text="@{user.name}"  //单向绑定数据变更自动通知UI
            android:textSize="@{@dimen/16sp}"//资源引用
            android:text="@{user.name+@string/suffix}"  //字符串的拼接需要引用资源 
            android:text="@{UserManager.getUserName()}" //调用静态方法,类必须先导入
            android:onClick="@{()-> UserManager.login()}"
          />

      <EditText
            //双向绑定数据变更自动更新UI,UI变更了也能自动更新user中name的数据,比单向绑定多个=
            android:text="@={user.name}" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

android:text="@{user.name}"等价于tvName.text = user.name这样就将数据和View相关联了。
那么如何实现View和数据的双向绑定呢?我们只需要让实体类User继承BaseObservable。当user中字段发生变更,只需要调用user.notifyPropertyChanged就可以让UI刷新。

public class User extends BaseObservable  {
    public String name;
    //当使用name字段发生变更后,若想UI自动刷新,我们需要给它写个get方法并且标记Bindable注解。
    //最后调用notifyPropertyChanged方法即可
    @Bindable                   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(com.mooc.ppjoke.BR.user);
    }
}

dataBinding 也支持在布局文件中使用 数组、LsitSetMap,且在布局文件中都可以通过 list[index] 的形式来获取元素,因为xml的特性,在声明 Lsit< String > 之类的数据类型时,需要使用尖括号的转义字符(在下面)

<?xml version="1.0" encoding="utf-8"?>
<layout >
    <data>
        <import type="java.util.List" /> <import type="java.util.Map" />
        <import type="java.util.Set" /> <import type="android.util.SparseArray" />
        <variable
            name="array"
            type="String[]" />
        <variable
            name="list"
            type="List&lt;String&gt;" />            //List<String> 其中<和>俩字符需要转义
        <variable
            name="map"
            type="Map&lt;String, String&gt;" />     //Map<String>
        <variable
            name="set"
            type="Set&lt;String&gt;" />                //Set<String>
        <variable
            name="sparse"
            type="SparseArray&lt;String&gt;" />  //SparseArray<String>
        <variable
            name="index"
            type="int" />
        <variable
            name="key"
            type="String" />
    </data>

    <LinearLayout>
        <TextView
            android:text="@{array[1]}" />

        <TextView
            android:text="@{sparse[index]}" />

        <TextView
            android:text="@{list[index]}" />

        <TextView
            android:text="@{map[key]}" />

        <TextView
            android:text='@{map["慕课jetpack"]}' />

        <TextView
            android:text='@{set.contains("xxx")?"慕课jetpack":key}' />
    </LinearLayout>
</layout>

dataBinding在xml中数据绑定支持的语法表达式也是非常丰富的,支持在布局文件中使用以下运算符、表达式和关键字:

算术运算符 + - / * %
字符串连接运算符 +
逻辑运算符 && ||
二元运算符 & | ^
一元运算符 + - ! ~
移位运算符 >> >>> <<
比较运算符 == > < >= <= (<需要被转义成&lt;>需要被转义为&gt;)
instanceof
分组运算符 ()
字面量运算符 - 字符、字符串、数字、null
类型转换,方法调用
字段访问
数组访问 []
三元运算符 ?

不支持以下操作 this,super,new,显示泛型调用

五、dataBinding如何拓展View属性
   public class PPImageView extends ImageView{

   //需要使用BindingAdapter注解并标记在public static方法上。
    //value中的字段随意添加和方法参数一一对应即可。
   @BindingAdapter(value = {"image_url", "isCircle"})
    public static void setImageUrl(PPImageView view, String imageUrl, boolean isCircle) {
        view.setImageUrl(view, imageUrl, isCircle, 0);
    }
    //requireAll = false代表是否以下三个属性在xml中同时使用才会调用到该方法
    //为false的话,只要有一个属性被使用就能调用到该方法
    @BindingAdapter(value = {"image_url", "isCircle", "radius"}, requireAll = false)
    public static void setImageUrl(PPImageView view, String imageUrl, boolean isCircle, int radius) {
       ......
      }
   }

//在布局文件中如下使用,便能实现图片圆角和资源Url绑定的功能
 <com.mooc.ppjoke.view.PPImageView
            .......
            app:image_url ="@{user.avatar}"
            app:radius="@{50}">
</com.mooc.ppjoke.view.PPImageView>
六、dataBinding使用的建议
一起拥抱Jetpack
1.Jetpack全系列组件高级用法&原理分析实战
2.Jetpack系列组件--LiveData从相遇到相知
3.Jetpack系列组件--ViewModel从相遇到相知
4.Jetpack系列组件--优雅的打造一款事件总线LiveDataBus
5.Jetpack系列组件--列表分页库Paging从相遇到相知
6.Jetpack系列组件--Navigation组件工作原理分析&灵活改造应用
7.Jetpack系列组件--dataBinding从相遇到相知
上一篇 下一篇

猜你喜欢

热点阅读