DataBinding 學(xué)習(xí)系列(2)詳解DataBinding在xml中的使用

前言#

上一篇簡單的介紹了DataBinding的用法,這幾篇來仔細的介紹一下<data>的功能。

data 標簽 的功能#

<data class="test"></data>

<h2>class 屬性</h2>
生成指定的名稱的Binding對象。

什么是Bind對象呢?來回顧之前的一句代碼

ViewDataBinding mBinder = DataBindingUtil.setContentView(this, R.layout.activity_main);

通過這一句,系統(tǒng)會自動幫助我們生成一個ViewDataBinding的子類,幫助我們操作xml中綁定的數(shù)據(jù),所以就需要給這個類起一個響亮的名字,根據(jù)Java的命名規(guī)則,R.layout.activity_main 就會默認生成 ActivityMainBinding,這個規(guī)則一看就明白。

class屬性就是幫助我們改變生成的類名和位置,有以下三種用法:

1、在模塊封裝包的databinding包中會生成名為TestBinding的Binding類。

<data class="TestBinding"></data>

2、在這個情況下,TestBinding類直接在模塊包種生成

<data class="TestBinding"></data>

3、在指定的包下生成Binding類。

<data class="com.example.TestBinding"></data>

如果沒有特殊需求,使用系統(tǒng)默認的命名就可以了。

那生成的ActivityMainBinding 與 ViewDataBinding 之間有什么區(qū)別呢??
最大的區(qū)別的就在于ActivityMainBinding中為設(shè)置的variable生成了setter 和 getter方法,設(shè)置綁定數(shù)據(jù)更加簡便。

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mBinder;

    private User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinder = DataBindingUtil.setContentView(this, R.layout.activity_main);
         // 設(shè)置綁定的user對象
        user = new User();
        user.setName("屌爆了");
        mBinder.setUser(user);
    
    // 綁定listener對象
        TestClickListener testClickListener = new TestClickListener();
        mBinder.setListener(testClickListener);
    }
    
    /**
      * 自定義的點擊回調(diào)監(jiān)聽
     **/
    public class TestClickListener {

        public void onClickListenerBinding(View view) {
            Toast.makeText(MainActivity.this, "1111", Toast.LENGTH_SHORT).show();
        }
    }

data 的子標簽#

<h2>variable</h2>

這個標簽之前已經(jīng)見過了,他用來綁定具體的對象的類。

<variable
    name="user"
    type="com.lzp.myapplication.bean.User"/>

<h2>import</h2>

<data>
    <import type="java.util.List"/>
    <variable name="users" type="List&lt;String&gt;" />
    <import type="com.example.util.StringUtil"/>
</data>

請注意,在xml中對于尖括號(<>)的使用是很嚴格的,否則會影響xml的正常解析,所以在這里必須對尖括號進行轉(zhuǎn)義,雖然會紅字報錯,但是是可以正常運行的。

import 表示引入引入某一個類,從上面看到引入了java.util.List,然后定了User的列表,還有引入了一個工具類 com.example.util.StringUtil。

name 是引用的名稱, type是具體的包名+類名,指明具體的類的地址。

那么如果引入了兩個相同類名的怎么辦?

<data>

    <import
        type="com.lzp.myapplication.bean.User" />

    <import
        type="com.lzp.myapplication.User"
        alias="User2" />

</data>

import 還有一個alias屬性,幫助我們來為引入的對象起別名,同樣可以引用,這樣就可以區(qū)別相同類名的不同類了。

如何使用data中引入和定義的內(nèi)容#

<h2>variable</h2>

使用variable中的bean對象,如果是屬性,直接使用@{name.field}

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}" />

如果使用的無參數(shù)方法,@{() -> name.function()}

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> listener.onClickListenerBinding()}"
            android:text="@{Utility.autoAppend(v,user.name)}" />

點擊事件需要把點擊的view傳入并操作,@{(v) -> name.function(v)}

括號中間的v就表示當前的這個view的參數(shù)名稱(可以自定義),直接作為參數(shù)名使用就可以。

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{(v) -> listener.onClickListenerBinding(v)}"
            android:text="@{user.name}" />

<h2>import</h2>

使用import引入的工具類,@{util.function()}

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Utility.autoAppend(user.name)}" />

目前在靜態(tài)方法不能通過使用bean的形式來傳入view參數(shù),具體解決辦法之后在介紹。

include#

Includes的使用

<?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">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
   </LinearLayout>
</layout>

系統(tǒng)會自動生成一個自定義屬性bind,通過bind可以直接對include中的layout中綁定的數(shù)據(jù)直接進行賦值,這樣就可以間接的控制include中的操作。

ViewStub#

如果是ViewStub怎么綁定??

binding = DataBindingUtil.setContentView(this, R.layout.activity_view_stub);
binding.viewStub.setOnInflateListener(new ViewStub.OnInflateListener() {
    @Override
    public void onInflate(ViewStub stub, View inflated) {
        ViewStubBinding binding = DataBindingUtil.bind(inflated);
        User user = new User("fee", "lang");
        binding.setUser(user);
    }
});

分析上面的代碼,首先ViewStub在尚未添加到xml中時,獲取Bindgin對象肯定是無效的,所以需要在OnInflateListener中回調(diào)被添加的事件,然后再去獲Bing對象。

總結(jié)#

我們已經(jīng)把DataBinding的大部分使用場景都已經(jīng)講過了,已經(jīng)能夠滿足大部分場景的需求,從一個小白直接飆升到了中級水平,但是勤能補拙,熟能生巧,我們還需要通過不懈的練習(xí)來鞏固所學(xué)的知識。有講錯的地方和不足請留言指出,大家一起學(xué)習(xí)進步。

下一篇我們來了解一下DataBinding 在 Java 代碼為我們具體提供了哪些重大的功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容