MVVM&Android实践(三):表达式语言

本文深入解析DataBinding中的表达式语言,涵盖操作符、避免空指针异常、资源语句及include标签的参数传递等核心内容,帮助开发者掌握布局文件中的动态数据绑定技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第三部分:表达式语言

常用操作符

DataBinding允许开发者在布局文件中使用表达式语言,就像在普通代码中一样。表达式语言中可供使用的操作符关键字如下:

  • 算术运算符:+ - / * %
  • 字符串连接符: +
  • 逻辑运算符:&& ||
  • 二进制操作符:& | ^
  • 一元运算符: + - ! ~
  • 位移运算符: >> >>> <<
  • 比较运算符:== > < >= <= (Note that < needs to be escaped as <)
  • instanceof
  • 分组()
  • Literals - character, String, numeric, null
  • Cast
  • 函数调用
  • Field 访问
  • 数组访问[]
  • 三元运算 ?:

Examples:

android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'

缺失操作符

  • this
  • super
  • new
  • Explicit generic invocation:普通的显式调用

这些操作符,应该不是缺失,而是压根儿就没打算支持,我表示理解,哈哈哈哈。

Null coalescing operator(??)

Null coalescing operator可以翻译为空合并运算符,符号是两个问号??,该操作符是二元操作符,示例代码如下:

android:text="@{user.displayName ?? user.lastName}"

该操作符返回一个非空的值:**如果左操作数不为空,返回左操作数,否则返回右操作数。**该实例代码类似于:

android:text="@{user.displayName != null ? user.displayName : user.lastName}"

避免非空指针异常

DataBinding生成的binding代码,自动检查值为null的变量,避免空指针异常。例如,在@{user.name}中,如果usernulluser.name将返回它的默认值null。如果你的引用是user.ageage的类型为int,此时data binding会使用它的默认值0

资源语句

使用如下语法,你可以在代码中获取资源。

dimens.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="height_little">1dp</dimen>
    <dimen name="height_large">10dp</dimen>
</resources>

strings.xml文件:

<resources>
    <string name="app_name">MVVMDemo</string>
    <string name="str_love">%s love %s</string>
</resources>

colors.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimaryDark">#00574B</color>
</resources>

布局文件edit_main.xml

<?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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:textSize="20dp"
            android:textColor="@{@color/colorPrimaryDark}"
            android:text='@{@string/str_love("I", "you.")}'
            android:padding="@{big ? @dimen/height_little:@dimen/height_large}"/>

    </LinearLayout>

    <data class="EditBinding">
        
        <variable
            name="big"
            type="boolean" />
    </data>
</layout>

Activity: EditTextActivity.java

public class EditTextActivity extends Activity {
    private Employ employ = new Employ("Kevin");
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EditBinding binding = DataBindingUtil.setContentView(this, R.layout.edit_main);
        binding.setBig(true);
    }
}

以上实例代码就是data binding中常见的使用场景了。

一般的资源,都可以通过这样的代码获取:

android:padding="@{big ? @dimen/height_little:@dimen/height_large}"

Tips:目前Android Studio在输入@dimen时并不会提示后续代码,需要你一个个敲出来。这点不是很方便。

对于格式化的字符串,需要使用参数的形式传递值:

<string name="str_love">%s love %s</string>
<!-- --------------------分割----------------------------- -->
android:text='@{@string/str_love("I", "you.")}'

参数的数量和占位符%s的数量一一对应即可。

include:传递参数

当布局文件中通过include标签包含其它布局时,我们需要将当前布局中的变量传递给include所包含的布局。需要用到app的namespace, 也就是需要再你的主布局文件中使用:

xmlns:bind="http://schemas.android.com/apk/res-auto"

将变量传递给include包含的子布局时,这样调用

<include
    layout="@layout/show_view"
    bind:user="@{user}" />

下面是完整代码:

Model文件:Employ.java

public class Employ {
    public final ObservableField<String> mName = new ObservableField<>();
    public Employ(String name) {
        mName.set(name);
    }
}

Include包含的子布局文件:show_view.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="user"
            type="com.superli.mvvmdemo.Employ" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="@{user.mName}"
            android:textSize="50dp"
            android:hint="HHHH"/>
    </LinearLayout>
</layout>

包含Include标签的主布局文件: include_main.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            layout="@layout/show_view"
            bind:user="@{user}" />
    </LinearLayout>

    <data class="IncludeBinding">

        <variable
            name="user"
            type="com.superli.mvvmdemo.Employ" />
    </data>
</layout>

Activity: IncludeActivity.java

public class IncludeActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IncludeBinding binding = DataBindingUtil.setContentView(this, R.layout.include_main);
        binding.setUser(new Employ("SuperLi"));
    }
}

看起来还是很简单的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值