Android Data Binding 进阶

Android Data Binding 初探
Android Data Binding 进阶
Android Data Binding 配合BaseAdapter

学完 Data Binding 的基本使用方法后,我们来学学 Data Binding 的进阶。

Data Binding 最大的作用就是减少我们在 Activity 写更新和设置 UI 代码,有时候,View的更新过程需要一些简单的逻辑,如判断空,拼接字段等,因此,Android 的 Data Binding 还提供了一些简单的表达式供我们在 xml 布局文件中使用。

例子:

数据类

public class Person extends BaseObservable {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }

    @Bindable
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        notifyPropertyChanged(BR.age);
    }

}

xml 布局文件

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

    <data>
        <variable
            name="person"
            type="com.johan.study.Person" />
    </data>

    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context="com.johan.study.MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="16dp"
            android:textColor="@android:color/holo_blue_light"
            android:text="@{person.name}"
            />

    </LinearLayout>

</layout>

Activity

public class MainActivity extends AppCompatActivity {

    private Person person = new Person(null, 25);
    private ActivityMainBinding binding;

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

}

如果看不懂,请看我博客 Android Data Binding 初探

三元表达式

更新 UI 最常用的逻辑应该是三元表达式了。我们来看看在 xml 布局文件中,三元表达式怎么使用:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16dp"
    android:textColor="@android:color/holo_blue_light"
    android:text="@{person.name != null ? person.name : @string/app_name}"
    />

所有表达式都要写在“@{}”里面:

@{person.name != null ? person.name : @string/app_name}

是不是和我们在 Java 代码写的一样呢?毫无违和感,爽!!

另外,在“@{}”内使用资源,也是和普通的一样,只不过没有提示(这点真的不太好,容易写错)。

三元表达式我们还能这么用:

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

    <data>
        <!-- import 标签的作用是引入类,和 java 代码一样 -->
        <!-- 因为在@{}中使用了View类,我们必须将包引入 -->
        <import type="android.view.View" />
        <variable
            name="person"
            type="com.johan.study.Person" />
    </data>

    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context="com.johan.study.MainActivity">

        <!-- visibility 属性使用了三元表达式,如果person的name为null,就设置为View.GONE,和 java 代码一样 -->
        <!-- 由于使用了 View 类,需要在data标签引入 View 类 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="16dp"
            android:textColor="@android:color/holo_blue_light"
            android:text="@{person.name != null ? person.name : @string/app_name}"
            android:visibility="@{person.name != null ? View.VISIBLE : View.GONE}"
            />

    </LinearLayout>

</layout>

上面的例子中,如果没有 import View 类的话,编译器是没有提示,你就应该想到要 import 了。

空运算符

Data Binding 还提供一个空运算符“??”

<TextView
    android:id="@+id/name_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16dp"
    android:textColor="@android:color/holo_blue_light"
    android:text="@{person.name ?? @string/app_name}"
    />

其实

@{person.name ?? @string/app_name}

就等同于

@{person.name != null ? person.name : @string/app_name}

拼接

我们可以在“@{}”内拼接字符

<TextView
    android:id="@+id/name_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16dp"
    android:textColor="@android:color/holo_blue_light"
    android:text="@{@string/app_name + person.name}"
    />

这样就可以拼接字符了:

@{@string/app_name + person.name}

我们还能拼接“dimen”,在 dimens 资源文件定义的两个距离

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="space_1">15dp</dimen>
    <dimen name="space_2">8dp</dimen>
</resources>

拼接 dimen 方式

<TextView
    android:id="@+id/name_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="@{@dimen/space_1 + @dimen/space_2}"
    android:textSize="16dp"
    android:textColor="@android:color/holo_blue_light"
    android:text="@{person.name}"
    />

我们看

@{@dimen/space_1 + @dimen/space_2}

这方便我们计算好距离,然后再设置,不用重新定义新距离,这个功能很有用的。

使用方法

我们在 xml 中不仅可以使用类实例的方法,还能直接使用类的静态方法,就好像 java 一样。

类实例方法就是我们设置的监听事件。

我们来看看怎么使用类的静态方法:

定义静态方法:

public class Utils {
    public static String formatName(String name) {
        return "姓名:" + name;
    }
}

xml 布局文件:

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

    <data>
        <!-- import 标签的作用是引入类,和 java 代码一样 -->
        <!-- 因为在@{}中使用了Util类,我们必须将包引入 -->
        <import type="com.johan.study.Utils" />
        <variable
            name="person"
            type="com.johan.study.Person" />
    </data>

    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context="com.johan.study.MainActivity">

        <!-- 使用 Utils.formatName 方法 -->
        <!-- 由于使用了 Utils类,需要在data标签引入 Utils 类 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="16dp"
            android:textColor="@android:color/holo_blue_light"
            android:text="@{Utils.formatName(person.name)}"
            />

    </LinearLayout>

</layout>

其实和我们使用 java 代码很相似,很多东西我们不妨用 java 代码试试!

使用数组和集合

在 xml 布局中,我们能定义一个数组,List,Map,通过访问下标,设置属性值。

网上查的我都试了,不知道为什么 Android Studio 不支持定义数组和具体List,暂时还没想到会用到这个,先放着吧!!(知道的,麻烦留言告知,谢谢! ^_^)

其他表达式

数学 + - / * %

字符串连接 +

逻辑 && ||

二进制 & | ^

一元运算 + - ! ~

移位 >> >>> <<

比较 == > < >= <=

instanceof

分组 ()

null

Cast

方法调用

数据访问 []

三元运算 ?:

其他表达式自己慢慢探索,你可以的!! just try!!

include

这里再补充一个,我们布局的时候,可能会用到“include”标签来复用布局。如果“include”的 layout 也是一个 Data Binding 的布局文件,里面还绑定了数据,那我们怎么赋值给“include”的 layout 的变量呢?

还是一个例子说明

layout_include.xml

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

    <data>
        <variable
            name="person"
            type="com.johan.study.Person" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/name_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="16dp"
            android:textColor="@android:color/holo_blue_light"
            android:text="@{person.name}"
            />
    </LinearLayout>

</layout>

“include”的文件里面定义了person变量。

activity_main.xml 布局文件

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

    <data>
        <variable
            name="person"
            type="com.johan.study.Person" />
        <variable
            name="handler"
            type="com.johan.study.MainActivity.NameHandler" />

    </data>

    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context="com.johan.study.MainActivity">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:hint="输入姓名"
            android:inputType="text"
            android:textSize="16dp"
            android:onTextChanged="@{handler.onTextChanged}"
            />

        <!-- 在 xml 文件直接传值给 include 的 layout 中 -->
        <include
            layout="@layout/layout_include"
            binding:person="@{person}"
            />

    </LinearLayout>

</layout>

我们通过 xml 文件可以直接把值赋给“include”layout 的 person 变量中,挺方便的!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值