DataBinding使用(一):布局和binding表达式

DataBinding使用(一):布局和binding表达式
DataBinding使用(二):可观察的数据对象
DataBinding使用(三):DataBinding高级使用

DataBinding通过数据绑定,可以直接在xml中绑定数据并实现一些处理逻辑,实时动态刷新数据。但是由于AndroidStudio对xml语法检查的贫弱,xml布局中的表达式逻辑错误,不能准确定位,debug难度增加。

一、环境配置

在Module级别的build.gradle上添加对DataBinding的支持

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

如果在library中使用,那么在该library的Module级别的build.gradle中也需要添加

二、布局和绑定

之前的布局文件是以LinearLayout、RelativeLayout等布局为根布局,DataBinding 的布局文件有些不同:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="user" type="com.test.databinding.data.User"/>
    </data>

    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
        <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"
                android:textSize="30dp"
                app:layout_constraintRight_toLeftOf="@+id/tv_age"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <TextView
                android:id="@+id/tv_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(user.age)}"
                android:textSize="30dp"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toRightOf="@+id/tv_name"
                app:layout_constraintTop_toTopOf="parent"/>


    </android.support.constraint.ConstraintLayout>
</layout>

通过语法表达式@{ }和变量user的属性设置到TextView

数据类
data class User( var name:String,var age:Int)
绑定数据

AndroidStudio 会根据layout 文件自动生成一个磨人的Binding类,类命根据layout文件名生成

 private lateinit var activityMainBinding: ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        var user = User("杨过",10)
        activityMainBinding.user = user
    }

在这里插入图片描述

三、表达式

支持的运算符

  • 数学运算符:+ - / * %
  • 字符串拼接: +
  • 逻辑运算符: && ||
  • 二进制: & | ^
  • 一元运算符:+ - ! ~
  • 位运算符: >> >>> <<<
  • 比较: == > < >= <=
  • instanceof
  • 组:()
  • 数据类型:字符, 字符串, 数字, null
  • 类型转换
  • 方法回调
  • 数组:[ ]
  • 三元操作符:?: 相当于??
    不支持的操作
  • this
  • super
  • new
  • 泛型
几个常用操作符
  • 非空判断
  android:text="@{user.name==null?user.name:`小龙女`}"

相当于
  android:text="@{user.name??`小龙女`}"

如果user为空,user.name 默认为null,如果In类型user.age为空,默认为0

  • 资源Resources
  android:text="@{user.name??@string/app_name}"
  • 集合
<data>
    <import type="android.util.SparseArray"/>
    <import type="java.util.Map"/>
    <import type="java.util.List"/>
    <variable name="list" type="List&lt;String&gt;"/>
    <variable name="sparse" type="SparseArray&lt;String&gt;"/>
    <variable name="map" type="Map&lt;String, String&gt;"/>
    <variable name="index" type="int"/>
    <variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"
四、variables、Imports、 includes
  • Variables
    data元素内可以使用多个variable元素,每个variable描述可以在布局上设置属性,用在布局中的表达式绑定
<data>
        <variable name="user" type="com.test.databinding.data.User"/>
    </data>
  • Imports
    Imports可以轻松的引用类型到布局文件中,在data元素内可以使用零个或多个import元素
<data>
    <import type="android.view.View"/>
</data>
...
<TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name==null?View.VISIBLE : View.GONE}"
                android:textSize="30dp"
                app:layout_constraintRight_toLeftOf="@+id/tv_age"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

如果类名有冲突时,可以给其中的一个类定义一个别名

<import type="android.view.View"/>
<import type="com.example.real.estate.View" alias="ViewRE"/>

这样就可以使用ViewRE来引用com.example.real.estate.View,而view就可以正常引用android.view.View

<data>
        <variable name="user" type="com.test.databinding.data.User"/>
    </data>

可以改写成

 <data>
        <import type="com.test.databinding.data.User"/>
        <variable name="user" type="User"/>
    </data>
  • Includes
    用法和以前一样,区别在于可以将变量传递到include布局的绑定中
<include layout="@layout/user"
                 app:user="@{user}"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 app:layout_constraintTop_toBottomOf="@+id/tv_name"
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent"
        />

user.xml 布局中必须声明user变量

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>

        <variable name="user" type="com.test.databinding.data.User"/>
    </data>

    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:context=".MainActivity">
        <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name??@string/app_name}"
                android:textSize="30sp"
                app:layout_constraintRight_toLeftOf="@+id/tv_age"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <TextView
                android:id="@+id/tv_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(user.age)}"
                android:textSize="30sp"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toRightOf="@+id/tv_name"
                app:layout_constraintTop_toTopOf="parent"/>


    </android.support.constraint.ConstraintLayout>
</layout>

在这里插入图片描述

五、事件处理

类似于android:onClick可以指定Activity 中的函数,DataBinding也允许处理从视图中发送的事件,有两种方式:
方法调用和监听绑定,二者的区别在于方法调用在编译时处理,监听绑定在事件发生时处理。

  • 方法调用
 class Events {
         fun showToast(view: View) {
             Toast.makeText(view.context, "我被点击了", Toast.LENGTH_SHORT).show()
     }
 <Button android:layout_width="wrap_content"
                android:id="@+id/button"
                android:layout_height="wrap_content"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:text="点击"
                android:onClick="@{events::showToast}"
                app:layout_constraintTop_toBottomOf="@+id/user_il"
              />

记得在activity中添加 activityMainBinding.events=Events(),刚开时用的时候经常忘记,造成方法调用不成功

  • 监听绑定
class Info {
    fun myInfo(view: View,user: User) {    
        Toast.makeText(view.context, "我是${user.name},我${user.age}岁", Toast.LENGTH_SHORT).show()

    }
}
 <Button android:layout_width="wrap_content"
                android:id="@+id/button2"
                android:layout_height="wrap_content"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:text="事件监听"
                android:onClick="@{()->info.myInfo(view,user)}"
                app:layout_constraintTop_toBottomOf="@+id/button1"
        />

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值