DataBinding可以在XML中使用事件的回調(diào)方法名作為屬性名(大部分情況下)來(lái)處理View分發(fā)的事件。比如說(shuō)View.OnLongClickListener的回調(diào)方法是onLongClick俄占,所以這個(gè)事件的屬性名稱就是android:onLongClick舶赔。
事件的處理可以有兩種方式:
- 方法引用:在事件屬性的表達(dá)式中調(diào)用一個(gè)方法,這個(gè)方法的簽名必須和事件回調(diào)方法簽名一致。當(dāng)事件回調(diào)發(fā)生時(shí)污茵,就會(huì)去轉(zhuǎn)而調(diào)用傳入的這個(gè)方法。如果事件表達(dá)式為空葬项,則只會(huì)給目標(biāo)view的事件回調(diào)設(shè)置一個(gè)空的監(jiān)聽器泞当。
- 監(jiān)聽器綁定:屬性值表達(dá)式是一個(gè)lambda表達(dá)式,總會(huì)創(chuàng)建一個(gè)監(jiān)聽器來(lái)設(shè)置到目標(biāo)view上民珍,事件發(fā)生的時(shí)候才會(huì)執(zhí)行這個(gè)表達(dá)式零蓉。
這兩種方式的主要區(qū)別是方法引用在綁定時(shí)就已經(jīng)給view設(shè)置了相對(duì)應(yīng)的監(jiān)聽了,而監(jiān)聽器綁定是方法觸發(fā)時(shí)才會(huì)去執(zhí)行表達(dá)式設(shè)置監(jiān)聽穷缤。
1. 方法引用
跟android:onClick
可以直接引用一個(gè)Activity中聲明的方法一樣敌蜂,事件也可以直接綁定到某個(gè)類的方法中,注意所綁定方法的參數(shù)必須與事件方法參數(shù)一致津肛,同時(shí)返回值也必須一致章喉。與View#onClick屬性相比,這種方式的優(yōu)點(diǎn)在于如果未設(shè)置相應(yīng)回調(diào)方法身坐,則編譯期就會(huì)報(bào)錯(cuò)秸脱,不會(huì)等到運(yùn)行時(shí)報(bào)錯(cuò)崩潰。使用示例:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.example.MainActivity"/>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:onClick="@{handlers::onClickFriend}"/>
</LinearLayout>
</layout>
public class MainAcivity extends Activity {
public void onClickFriend(View view) { ... }
}
調(diào)用語(yǔ)法可以是@{handlers::onClickFriend}
或者@{handlers.onClickFriend}
部蛇。
2. 監(jiān)聽器綁定
事件發(fā)生時(shí)才會(huì)執(zhí)行屬性值里的表達(dá)式摊唇。跟方法引用不同的是,表達(dá)式內(nèi)可以寫任意的DataBinding表達(dá)式涯鲁。而且監(jiān)聽器綁定可以定義不同的參數(shù)類型巷查,只要表達(dá)式返回值與事件方法返回值一致就可以了,如果事件方法返回值是空抹腿,表達(dá)式可以不用返回岛请。
監(jiān)聽器綁定的格式如下:
public class Presenter {
public void onSaveClick(Task task){}
}
<!-- XML -->
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.android.example.Task" />
<variable name="presenter" type="com.android.example.Presenter" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onSaveClick(task)}" />
</LinearLayout>
</layout>
使用的是lambda表達(dá)式,并且lambda表達(dá)式必須是表達(dá)式的最外層警绩。
上述格式中我們省略了onClick的參數(shù)View崇败,監(jiān)聽器綁定中可以省略所有或者列出所有監(jiān)聽器的參數(shù)。列出所有參數(shù)的格式如下:
android:onClick="@{(view) -> presenter.onSaveClick(task)}"
聲明了參數(shù)之后就可以在表達(dá)式中使用:
public class Presenter {
public void onSaveClick(View view, Task task){}
}
<!-- XML -->
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
Lambda表達(dá)式多個(gè)參數(shù)的示例:
<CheckBox
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
注意監(jiān)聽器綁定的返回值必須與回調(diào)方法返回值一致肩祥,例如:
public class Presenter {
public boolean onLongClick(View view, Task task){}
}
<!-- XML -->
android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
假如監(jiān)聽器方法返回null后室,則會(huì)為回調(diào)方法返回其返回值的默認(rèn)值。
另外可以在lambda表達(dá)式中可以使用void:
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"