以前寫了Android數據綁定DataBinding(一)入門篇,很簡單的記錄瞭如何使用DataBinding,其初衷是想要代碼中的數據發生改變,不須要繁瑣的setText等操做,在最後說到了只須要將POJO繼承一個BaseObservable便可,其實這只是冰山一角啦!!!android
本文如有出入,請指正——來自小渣渣的顫抖
客官可移步小站查看本文http://fanjiajia.cn/2019/07/07/Android/flx1/
本文接着上一篇的內容,記錄一下數據對象
和事件處理
ide
其實繼承BaseObservable的javBean叫作數據對象,官網介紹以下:佈局
Any plain old Java object (POJO) may be used for data binding, but modifying a POJO will not cause the UI to update. The real power of data binding can be used by giving your data objects the ability to notify when data changes. There are three different data change notification mechanisms, Observable objects, observable fields, and observable collections. When one of these observable data object is bound to the UI and a property of the data object changes, the UI will be updated automatically.
大意是:學習
任何普通的Java對象(POJO)均可以用於數據綁定,但修改POJO不會致使UI更新。當數據改變的時候,您的數據對象可以發出通知,這纔是數據綁定的威力。有三種不一樣的數據更改通知機制: Observable對象,observable字段, 和observable集合. 當這些observable數據對象之一被綁定到UI而且數據對象的屬性改變時,UI將被自動更新。
這個就是我在Android數據綁定DataBinding(一)入門篇中最後介紹的那樣,將咱們的Bean繼承 BaseObservable,這裏再貼一下code;this
public class User extends BaseObservable{ private String userName; private int age; public User(String userName, int age) { this.userName = userName; this.age = age; } @Bindable public String getUserName() { return userName == null ? "" : userName; } public void setUserName(String userName) { this.userName = userName; notifyPropertyChanged(BR.userName); } @Bindable public int getAge() { return age; } public void setAge(int age) { this.age = age; notifyPropertyChanged(BR.age); } @Override public String toString() { return "User{" + "userName='" + userName + '\'' + ", age=" + age + '}'; } }
能夠看到在setter方法中調用了notifyPropertyChanged(BR.age);
文檔中這樣介紹道:The Observable interface has a mechanism to add and remove listeners, but notifying is up to the developer.
也就是說,這種機制容許開發者本身對被監聽的字段進行添加和刪除,個人理解就是(看你本身想綁定那些字段)。code
相比於上一種方式,使用ObservableFields則能夠減小許多的工做量,由於咱們能夠許多提供的類型,文檔介紹以下:ObservableField and its siblings ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, and ObservableParcelable.
示例:xml
public class People { public ObservableField<String> name = new ObservableField<>(); public ObservableInt age = new ObservableInt(); public ObservableList<String> list = new ObservableArrayList<>(); public People(String name, int age, ArrayList<String> list) { this.name = new ObservableField<>(name); this.age = new ObservableInt(age); this.list = (ObservableArrayList)list; } }
這樣就不須要咱們本身在getter上設置@binding
,在setter中設置notifyPropertyChanged(int)
了。對象
官方列舉了這樣兩個例子,ObservableArrayMap
和ObservableArrayList
,其中對ObservableArrayMap
的介紹是key是String這樣的類型時,是很是有用的,示例以下:繼承
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
在layout中three
<data> <import type="android.databinding.ObservableMap"/> <variable name="user" type="ObservableMap<String, Object>"/> </data> … <TextView android:text='@{user["lastName"]}' android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text='@{String.valueOf(1 + (Integer)user["age"])}' android:layout_width="wrap_content" android:layout_height="wrap_content"/>
個人理解就是一些集合類型的封裝使用。
以前對某個View設置某種監聽事件是經過setXXXX,在數據綁定中是如何實現的呢,有兩種方式
監聽器綁定(Listener Bindings)
<variable name="presenter" type="com.jiajia.mypractisedemos.module.jetpack.JetpackActivity.Presenter"/> ...... <Button android:text="click" android:textAllCaps="false" android:onClick="@{presenter.onClick}" android:layout_width="wrap_content" android:layout_height="wrap_content" />
public class Presenter { public void onClick(View view) { people.name.set("啊啊啊啊啊"); Toast.makeText(JetpackActivity.this, "點擊了Button",Toast.LENGTH_SHORT).show(); } }
這裏注意必須給定參數View view,即須要符合事件監聽的寫法。
這個說真的,沒特別理解,簡單整理一下,英文文檔說:在方法引用中,方法的參數必須與事件監聽器的參數匹配。在監聽器綁定中,只有你的返回值必須與監聽器的指望返回值相匹配(除非它預期爲void),例如:
public class Presenter { public void onSaveClick(Task task){} }
而後,您能夠將click事件綁定到您的類,以下所示:
<?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>
注意這裏沒有傳入view參數,可能這就是與方法引用不一樣之處,固然也能夠傳啦,android:onClick="@{(view) -> presenter.onSaveClick(task)}"
,還有好幾種,也不知道什麼狀況下用,也不懂,不寫了,之後用到再說。我以爲就方法引用的方式用得比較多,比較太low了平時寫的代碼。
方法引用和監聽器綁定的主要區別在於實際的監聽器實現是在綁定數據時建立的,而不是在事件觸發時建立的。若是您喜歡在事件發生時計算表達式,則應該使用監聽器綁定。
下午6點了,好餓,去食堂吃麻辣燙了!
此致,敬禮