前言#
上一篇簡單的介紹了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<String>" />
<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 代碼為我們具體提供了哪些重大的功能。