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

第三部分:表达式语言

常用操作符

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"));
    }
}

看起来还是很简单的。

发布了79 篇原创文章 · 获赞 30 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章