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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章