• 主页
  • 归档
所有文章 友链 关于我

  • 主页
  • 归档

Android DataBinding(二)进阶用法

2021-11-18

在《Android-DataBinding(一)基础》一文中对 DataBinding 的接入和使用进行了介绍。本文将会针对 DataBinding 中一些琐碎的知识点进行介绍,比如:Class 属性、Default 属性、Resource 引用等,这些属性被使用的频率或许不是很高,但特定的情况下却会起到意想不到的作用。下面将会针对这些属性进行逐一的讲解。

1. Data 标签的 Class 属性

默认情况下,系统会根据布局文件的名称生成对应的 ViewDataBinding 子类,帮助我们操作 XML 中绑定的数据,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.sunzn.data;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.sunzn.data.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}

}

如果你想改变默认的 ViewDataBinding 子类名称或位置,这时就可以通过 class 属性完成命名和位置的变更,如下所示:

1
2
3
4
5
6
7
8
9
<data class="ActivityUserBinding">

<import type="com.sunzn.bind.User" />

<variable
name="user"
type="User" />

</data>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.sunzn.data;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.sunzn.data.databinding.ActivityUserBinding;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityUserBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}
}

上面通过 class 属性完成了命名的变更。如需改变类所属的包名,只需在类的名称前增加对应的包名即可,如下所示:

1
2
3
4
5
6
7
8
9
<data class="com.sunzn.bind.ActivityUserBinding">

<import type="com.sunzn.bind.User" />

<variable
name="user"
type="User" />

</data>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.sunzn.data;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.sunzn.bind.ActivityUserBinding;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityUserBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}
}

2. Default 属性

通常情况下,我们可以通过 Android Studio 来预览布局文件的展示效果,例如预览 TextView 的文字颜色、大小等。但是使用了 DataBinding 布局预览就会变得极不方便,所以 DataBinding 提供了设置默认值的功能。如下所示:

1
2
3
4
<androidx.appcompat.widget.AppCompatTextView
......
android:text="@{user.name, default=`sunzn is a man`}"
...... />

✦ 注意: 这里的 default 属性,是为布局预览而提供的,项目运行后并不会显示,其作用和 tools:text=”预览” 类似。语法就是在完整的属性值最后用英文逗号隔开,加上 default=xxxx,如果预览的文字包含空格,则需要用反引号进行包裹。

该属性还可以对控件的 visibility 默认值进行配置,同时也可以结合三元运算符进行动态控制。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<import type="android.view.View" />

<import type="com.sunzn.bind.User" />

<variable
name="user"
type="User" />

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.appcompat.widget.AppCompatTextView
......
android:visibility="@{user.id > 0 ? View.VISIBLE : View.GONE, default=gone}"
...... />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

✦ 注意: 如果布局文件中使用到了 View 类,则需要在 data 标签内导入 View 类;另外,需要特别注意 default=gone 的写法。

3. Resource 引用

DataBinding 可以对各种资源文件进行引用,比如可以引用 values/strings.xml 下各种格式的字符资源。如下所示:

1
2
3
4
5
6
<!--strings.xml-->

<resources>
<string name="app_name">data</string>
<string name="user_data">编号%1$d,姓名%2$s</string>
</resources>
1
2
3
4
<androidx.appcompat.widget.AppCompatTextView
......
android:text="@{@string/app_name}"
....../>
1
2
3
4
<androidx.appcompat.widget.AppCompatTextView
......
android:text="@{@string/user_data(user.id, user.name)}"
...... />

除了可以引用字符资源,还可引用 values/dimens.xml 下的尺寸资源。如下所示:

1
2
3
4
5
6
7
<!--dimens.xml-->

<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="largePadding">100dp</dimen>
<dimen name="smallPadding">10dp</dimen>
</resources>
1
2
3
4
<androidx.appcompat.widget.AppCompatTextView
......
android:padding="@{user.id > 0 ? @dimen/largePadding : @dimen/smallPadding}"
....../>

✦ 注意: 经测试 margin 属性不支持这种形式的赋值,现阶段仅支持 padding 及 paddingStart 等属性。

除了可以引用尺寸资源,还可引用 drawable 下的图片以及 XML 资源。如下所示:

1
2
3
4
<androidx.appcompat.widget.AppCompatTextView
......
android:background="@{user.id > 0 ? @drawable/ic_background : @drawable/ic_foreground}"
...... />

✦ 注意: 经测试 mipmap 下的资源文件不支持这种形式的赋值,现阶段只支持 drawable 下的资源文件。

4. 点击事件

点击事件的绑定可以在 <data> 节点下导入系统默认的 OnClickListener 类,然后将其绑定到控件上。这种方式的绑定需要在 OnClickListener 的实现类里对被点击控件的 ID 进行区分,使用方式和之前并无多大区别。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<import type="com.sunzn.bind.User" />

<import type="android.view.View.OnClickListener" />

<variable
name="user"
type="User" />

<variable
name="clickListener"
type="OnClickListener" />

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/user_id"
android:onClick="@{clickListener}"
...... />

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/user_name"
android:onClick="@{clickListener}"
...... />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.sunzn.data;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.sunzn.bind.User;
import com.sunzn.data.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setClickListener(this);
User user = new User(1, "sunzn");
binding.setUser(user);
}

@Override
public void onClick(View v) {
int ID = v.getId();
if (ID == R.id.user_id) {
Toast.makeText(v.getContext(), "点击了用户编码", Toast.LENGTH_SHORT).show();
return;
}
if (ID == R.id.user_name) {
Toast.makeText(v.getContext(), "点击了用户姓名", Toast.LENGTH_SHORT).show();
}
}

}

点击事件的另一种绑定方式是在 <data> 节点下导入点击方法的持有类,然后将其绑定到控件上。这种方式的绑定无需对被点击控件的 ID 进行区分,因为控件的 onClick 属性直接指向了具体的方法,所以在一定程度上简化了传参。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<import type="com.sunzn.bind.User" />

<import type="com.sunzn.data.MainActivity.ClickListener" />

<variable
name="user"
type="User" />

<variable
name="clickListener"
type="ClickListener" />

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/user_id"
android:onClick="@{()->clickListener.onUserIDClick()}"
...... />

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/user_name"
android:onClick="@{()->clickListener.onUserNameClick()}"
...... />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.sunzn.data;

import android.os.Bundle;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.sunzn.bind.User;
import com.sunzn.data.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setClickListener(new ClickListener());
User user = new User(1, "sunzn");
binding.setUser(user);
}

public class ClickListener {
public void onUserIDClick() {
Toast.makeText(MainActivity.this, "点击了用户编码", Toast.LENGTH_SHORT).show();
}

public void onUserNameClick() {
Toast.makeText(MainActivity.this, "点击了用户姓名", Toast.LENGTH_SHORT).show();
}
}

}
赏

谢谢你请我吃糖果

  • DataBinding

扫一扫,分享到微信

微信分享二维码
Android DataBinding(三)单向绑定-BaseObservable
Android DataBinding(一)基础
  1. 1. 1. Data 标签的 Class 属性
  2. 2. 2. Default 属性
  3. 3. 3. Resource 引用
  4. 4. 4. 点击事件
© 2025 狮子
京ICP备14032650号
  • 所有文章
  • 友链
  • 关于我

tag:

  • Android
  • WebView
  • DataBinding
  • ActiveMQ
  • NDK
  • Android Studio
  • Error
  • Lombok
  • Room
  • SQLite
  • 组件化
  • Fragment
  • File
  • Theme
  • View
  • Java
  • Annotation
  • Fiddler
  • Glide
  • Hexo
  • Json
  • JitPack
  • Generics
  • Thread
  • Kotlin
  • MySQL
  • 算法
  • 面试
  • Python
  • FTP
  • ADB
  • Issue
  • 方案
  • 设计模式
  • Permission
  • SVN
  • Crack
  • Wireshark
  • Charles
  • Burpsuite
  • Version
  • Signature
  • ConstraintLayout
  • Bitmap
  • Application

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 极简便签

    2035-04-28

    #Application

  • Android Studio 里有用的快捷键

    2025-08-12

    #Android

  • ExpiredTargetSdkVersion

    2025-07-16

    #Error

  • Android 启动画面的深色主题

    2025-04-20

    #Theme

  • 如何在 SQLite 中切换布尔值

    2025-02-27

    #SQLite

  • Kotlin 通过委托实现接口方法

    2025-01-15

    #Kotlin

  • Kotlin 中的中缀函数

    2025-01-14

    #Kotlin

  • 华为手机消息角标问题排查过程

    2024-08-21

    #Issue

  • 约束布局下的 Chains

    2024-05-23

    #Android#ConstraintLayout

  • 约束布局下的 Guideline

    2024-05-21

    #Android#ConstraintLayout

  • Android MQTT Client

    2024-04-08

    #ActiveMQ

  • ActiveMQ MQTT Server 搭建

    2024-04-08

    #ActiveMQ

  • Kotlin 中的内部类

    2023-08-09

    #Kotlin

  • Kotlin 中的扩展函数与属性

    2023-08-08

    #Kotlin

  • Kotlin 中的数据操作

    2023-06-06

    #Kotlin

  • 为什么 Fragment 需要一个无参构造函数

    2023-05-04

    #Fragment

  • 从 APK 签名包安装失败说起

    2023-03-21

    #Android#Issue

  • SQLite 中的 IFNULL() 函数

    2023-02-21

    #SQLite

  • Android 访问文件与目录

    2023-01-30

    #Android#File

  • 下载引擎的组件化之路

    2022-12-28

    #组件化

  • 后台弹出界面权限

    2022-11-24

    #Permission

  • SQLite 数据清洗

    2022-10-19

    #SQLite

  • Android 依赖模块分组

    2022-09-23

    #组件化

  • Java 8 Stream

    2022-03-08

    #Java

  • Android Studio 离线安装 Lombok 插件

    2022-03-07

    #Lombok

  • Android DataBinding(三)单向绑定-BaseObservable

    2021-11-19

    #DataBinding

  • Android DataBinding(二)进阶用法

    2021-11-18

    #DataBinding

  • Android DataBinding(一)基础

    2021-11-17

    #DataBinding

  • DataBinding 下的 EditText 绑定 TextChangedListener

    2021-11-16

    #DataBinding

  • Java 的同步化

    2020-06-17

    #Thread

  • 单例模式的安全性演进

    2020-06-14

    #设计模式

  • Android M 的 NDK 行为变更对 APK 包体积的影响

    2020-06-05

    #Android#NDK

  • 手机抓包的几种方式

    2020-03-27

    #Fiddler#Crack#Wireshark#Charles#Burpsuite

  • Java 泛型中 extends 和 super 的区别

    2020-03-11

    #Generics

  • Kotlin 中的 Constructor

    2020-01-12

    #Kotlin

  • Kotlin 中的 Elvis 操作符 ?:

    2020-01-08

    #Kotlin

  • Excel 数据导入 SQLite

    2019-05-09

    #Android#SQLite

  • Android P 行为变更对 WebView 的影响

    2019-04-18

    #Android#WebView

  • Time 在 Room 中的使用

    2019-02-28

    #Android#Room#SQLite

  • Android Room 使用指南

    2019-02-23

    #Android#Room#SQLite

  • Library 声明的 minSdkVersion 大于 Module 的怎么办?

    2019-02-21

    #Android

  • Android 中的调色板 Palette

    2019-01-31

    #Android

  • JitPack:Failed to install the following Android SDK packages as some licences have not been accepted

    2019-01-21

    #JitPack

  • 自定义 View 感知事件的几种方式

    2018-11-08

    #Android#View

  • Android Library 中 switch 语句的 case 不能访问资源 ID 的原因

    2018-08-12

    #Android

  • 标识应用所在的 Android 设备

    2018-08-07

    #Android

  • Windows 10 下配置 ADB 环境变量

    2018-08-01

    #ADB

  • 将 Android 项目托管到 SVN 上

    2018-05-27

    #SVN

  • Glide V4 API 变更指南

    2018-05-26

    #Glide

  • 将 Java 对象注入到 WebView 的 JavaScript 上下文

    2018-04-26

    #Android#WebView

  • Android 自定义控件-音频可视化

    2018-04-19

    #Android#View

  • Android 中的 Fragment 懒加载

    2018-04-18

    #Android#Fragment

  • N 个无序数中找出最大的 M 个数

    2018-03-30

    #算法#面试

  • 高效加载大图

    2018-03-22

    #Android#Bitmap

  • 管理 Android 设备唤醒状态

    2018-01-30

    #Android

  • Android 5.0 行为变更对 WebView 的影响

    2018-01-24

    #Android#WebView

  • SQLite 存储类

    2017-11-27

    #SQLite

  • SQLite 数据库管理

    2017-11-25

    #SQLite

  • SQLite 事务

    2017-11-24

    #SQLite

  • SQLite 索引

    2017-11-23

    #SQLite

  • SQLite 视图

    2017-11-22

    #SQLite

  • SQLite 触发器

    2017-11-20

    #SQLite

  • SQLite 中的 Null

    2017-11-20

    #SQLite

  • SQLite 插入、更新或忽略

    2017-11-19

    #SQLite

  • SQLite 修改数据

    2017-11-18

    #SQLite

  • 如何从 SQLite 的现有表中添加或删除列

    2017-11-17

    #SQLite

  • Python(2.4)重点复习

    2017-10-17

    #Python

  • Python(2.3)使用 IDE

    2017-10-14

    #Python

  • Python(2.2)模块与包

    2017-10-13

    #Python

  • MySQL数据库插入中文乱码的解决方案

    2017-10-10

    #MySQL

  • JSONArray 值为 NULL 时的容错处理

    2017-10-10

    #Json

  • Android Studio : Failed to open zip file

    2017-09-05

    #Android Studio#Error

  • 自定义 View(三)文字的绘制

    2017-08-24

    #Android#View

  • 自定义 View(二)Paint 详解

    2017-08-23

    #Android#View

  • 自定义 View(一)绘制基础

    2017-08-22

    #Android#View

  • 自定义 View 基础 - 角度与弧度

    2017-08-21

    #Android#View

  • 自定义 View 基础 - 坐标系

    2017-08-21

    #Android#View

  • Fiddler(四)状态栏

    2017-08-20

    #Fiddler

  • Fiddler(三)工具栏

    2017-08-20

    #Fiddler

  • Fiddler(二)主菜单

    2017-08-14

    #Fiddler

  • Fiddler(一)用户界面

    2017-08-10

    #Fiddler

  • TP-LINK 映射内网 FTP 服务到外网

    2017-08-09

    #FTP

  • Python(2.1)Python 学习之使用 REPL

    2017-08-07

    #Python

  • Python(1.1)下载与安装 Python 3.6

    2017-08-05

    #Python

  • 由 zipalign 导致的签名无效

    2017-08-03

    #Android#Signature

  • 版本号

    2017-08-02

    #Version

  • Windows 下 MySQL 数据库 Root 密码重置

    2017-07-29

    #MySQL

  • 泛型

    2017-07-28

    #Java#Generics

  • Annotation 概述

    2017-07-20

    #Java#Annotation

  • 使用 URL Scheme 唤起应用打开 Activity

    2017-07-18

    #方案

  • 面试题:反转

    2017-07-13

    #算法#面试

  • Java 字符串格式化 String.format() 的使用

    2017-07-05

    #Java

  • Hexo下删除文章

    2017-06-01

    #Hexo

  • Hexo下新建文章

    2017-05-31

    #Hexo

  • Google Developers Blog
  • Android 开发者 • 中国
  • Android 开发者 • 美国
  • Android 开发者 • 指南
  • Android 开发者 • 版本
  • Flutter 中文开发者网站
  • Kotlin 语言中文站
  • Java SE 6 技术手册
  • 阿里巴巴矢量图标库
  • 小松的技术博客
  • Quick Reference
  • ConstraintLayout
  • Chris Banes
  • HenCoder
  • GcsSloop
  • Gityuan
  • HuKai
  • 刘望舒
  • 于卫国
  • 木水川
  • 木水川@ChinaUnix
  • 魏超
  • 振兴
  • James Smith
  • Mastering Markdown
  • Dan Lew
  • Jeroen Mols
慢慢的
慢慢的
去改变世界