DataBinding(三)事件處理

DataBinding可以在XML中使用事件的回調方法名作爲屬性名(大部分情況下)來處理View分發的事件。比如說View.OnLongClickListener的回調方法是onLongClick,所以這個事件的屬性名稱就是android:onLongClick。

事件的處理可以有兩種方式:
1. 方法引用:在事件屬性的表達式中調用一個方法,這個方法的簽名必須和事件回調方法簽名一致。當事件回調發生時,就會去轉而調用傳入的這個方法。如果事件表達式爲空,則只會給目標view的事件回調設置一個空的監聽器。
2. 監聽器綁定:屬性值表達式是一個lambda表達式,總會創建一個監聽器來設置到目標view上,事件發生的時候纔會執行這個表達式。

這兩種方式的主要區別是方法引用在綁定時就已經給view設置了相對應的監聽了,而監聽器綁定是方法觸發時纔會去執行表達式設置監聽。

1. 方法引用

android:onClick可以直接引用一個Activity中聲明的方法一樣,事件也可以直接綁定到某個類的方法中,注意所綁定方法的參數必須與事件方法參數一致,同時返回值也必須一致。與View#onClick屬性相比,這種方式的優點在於如果未設置相應回調方法,則編譯期就會報錯,不會等到運行時報錯崩潰。使用示例:

<?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) { ... }
}

調用語法可以是@{handlers::onClickFriend}或者@{handlers.onClickFriend}

2. 監聽器綁定

事件發生時纔會執行屬性值裏的表達式。跟方法引用不同的是,表達式內可以寫任意的DataBinding表達式。而且監聽器綁定可以定義不同的參數類型,只要表達式返回值與事件方法返回值一致就可以了,如果事件方法返回值是空,表達式可以不用返回。

監聽器綁定的格式如下:

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表達式,並且lambda表達式必須是表達式的最外層。

上述格式中我們省略了onClick的參數View,監聽器綁定中可以省略所有或者列出所有監聽器的參數。列出所有參數的格式如下:

 android:onClick="@{(view) -> presenter.onSaveClick(task)}"

聲明瞭參數之後就可以在表達式中使用:

public class Presenter {
    public void onSaveClick(View view, Task task){}
}

<!-- XML -->
  android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"

Lambda表達式多個參數的示例:

 <CheckBox 
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />

注意監聽器綁定的返回值必須與回調方法返回值一致,例如:

public class Presenter {
    public boolean onLongClick(View view, Task task){}
}

<!-- XML -->
 android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"

假如監聽器方法返回null,則會爲回調方法返回其返回值的默認值。

另外可以在lambda表達式中可以使用void:

 android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章