Data binding 入坑筆記二進階篇之雙向綁定
上一篇介紹了Data binding的基礎用法,你可能會想這也太基礎了,只支持前置數據的綁定,一旦數據變化了UI都監聽不到。不要著急,這一篇就來講到databinding的雙向綁定用法。
0.舉個例子
我們用一個輸入控件EditText和一個文本控件TextView來舉個栗子,我們想要在TextView要獲取文本框內容,原始寫法首先獲取兩個控件的對象,然后設置輸入框監聽對象,最后賦值給TextView做顯示,算了算需要寫三步呢
我們來看看Data Binding的代碼,只需要把對象綁定進去就好了
public class TwowayActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_twoway);
ActivityTwowayBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_twoway);
binding.setStudent(new Student());
}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="student"
type="com.jie.databindingsimple.entity.Student"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入內容"
android:text="@={student.name}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{student.name}"/>
</LinearLayout>
</layout>
1. Observable Binding
Data Binding本身是不支持雙向綁定的,我們想要實現雙向綁定首先要改造一下實體類。讓實體類繼承BaseObservable
,來看例子
public class Student extends BaseObservable {
private String name;
private String className;
@Bindable
public String getName() {
return name;
}
@Bindable
public String getClassName() {
return className;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
public void setClassName(String className) {
this.className = className;
notifyPropertyChanged(BR.className);
}
}
BR
是編譯階段生成的一個類,功能與 R.java 類似,用 @Bindable
標記過 getter
方法會在BR
中生成一個靜態常量。
public class BR {
public static final int _all = 0;
public static final int className = 1;
public static final int name = 2;
public static final int student = 3;
public static final int user = 4;
}
在setter
方法里我們需要用notifyPropertyChanged
方法來更新對象。
還有另一種適用于POJO的寫法,這種寫法不需要繼承BaseObservable
,不過每個成員變量都要new
一個ObservableField
對象。
public class Teacher {
public final ObservableField<String> name = new ObservableField<>();
public final ObservableField<String> className = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
2. xml寫法
如果想在輸入的時候給變量賦值,則需要用到@={}
這個操作符,{}
里面是我們想要賦值的對象
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入內容"
android:text="@={student.name}"/>
3.原理解析
InverseBindingListener
是事件發生時觸發的監聽器,所有雙向綁定,最后都是通過這個接口來observable
改變的,各種監聽,比如TextWatcher
、OnCheckedChange
,都是間接通過這個接口來通知的。在ActivityTwowayBinding
的源碼中我們可以找到這個方法片段。
// values
// listeners
// Inverse Binding Event Handlers
private android.databinding.InverseBindingListener mboundView1androidTextAttrChanged = new android.databinding.InverseBindingListener() {
@Override
public void onChange() {
// Inverse of student.name
// is student.setName((java.lang.String) callbackArg_0)
java.lang.String callbackArg_0 = android.databinding.adapters.TextViewBindingAdapter.getTextString(mboundView1);
// localize variables for thread safety
// student
com.jie.databindingsimple.entity.Student student = mStudent;
// student.name
java.lang.String studentName = null;
// student != null
boolean studentJavaLangObjectNull = false;
studentJavaLangObjectNull = (student) != (null);
if (studentJavaLangObjectNull) {
student.setName(((java.lang.String) (callbackArg_0)));
}
}
};
我們通過java.lang.String callbackArg_0 = android.databinding.adapters.TextViewBindingAdapter.getTextString(mboundView1);
獲取到EditText上輸入的值,來看看getTextString
方法
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
public static String getTextString(TextView view) {
return view.getText().toString();
}
InverseBindingAdapter
用于關聯某個用于接收View
變更的方法,有兩個參數attribute
描述和event
事件,獲取到數據后我們拿到student對象,然后給他賦值student.setName(((java.lang.String) (callbackArg_0)));
4. 屬性改變監聽
如果有兩個輸入框,我們要監聽輸入對象的改變怎么辦,如下:
我們可以利用Observable
中的addOnPropertyChangedCallback
來實現。先來看看Observable
類,里面有添加回調、刪除回調等方法。
package android.databinding;
public interface Observable {
void addOnPropertyChangedCallback(Observable.OnPropertyChangedCallback var1);
void removeOnPropertyChangedCallback(Observable.OnPropertyChangedCallback var1);
public abstract static class OnPropertyChangedCallback {
public OnPropertyChangedCallback() {
}
public abstract void onPropertyChanged(Observable var1, int var2);
}
}
在onCreate
中實現添加callback
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_twoway);
ActivityTwowayBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_twoway);
Student student = new Student();
binding.setStudent(student);
student.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable observable, int i) {
switch (i) {
case BR.name:
Toast.makeText(TwowayActivity.this, "name", Toast.LENGTH_SHORT).show();
break;
case BR.className:
Toast.makeText(TwowayActivity.this, "classname", Toast.LENGTH_SHORT).show();
break;
}
}
});
}
5. 雙向綁定場景范圍
目前雙向綁定僅支持如text,checked,year,month,hour,rating,progress等綁定。
智能推薦
android -------- Data Binding的使用(一)
Google推出自己官方的數據綁定框架Data Binding Library 已經很久了,很多企業也在使用 面試的時候也有問到,所以也去學習了一番,特來分享一下,希望對各位有所幫助 描述: Data Binding 是把數據直接綁定到 XML 文件上,并能實現自動刷新。 Data Binding 減少了代碼的耦合性,一些如 findViewById、setText 之類的操作都可以...
Android---Data Binding使用入門
Android---Data Binding使用入門 2016年09月22日 14:41:14 閱讀數:466 一直沒使用過Data Binding,今天就來學習一下,有興趣的朋友可以直接看官網的介紹Data Binding 準備工作 首先要在build.gradle中添加一句 1 2 3 添加的位置是這樣的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 然后準備好...
UI5的Data binding
學習了解一下UI5的數據binding UI5作為一個成熟的企業級UI開發框架,其最大的特點就是遵循MVC的設計,也就是將代碼邏輯清晰地區分為數據源(model) - UI(view) - 應用邏輯(controller)這三部分。數據binding就是model和view之間如何交互。 UI5的數據binding主要有三種方式: Property binding Aggregation bind...
c#中的data binding
Data Binding Overview WPF用data binding來創建UI和數據的關聯。其中數據的來源可以是common language runtime objects或者是XML. wpf中的data binding相對于傳統的模型有很多優勢: 1. UI的大多數屬性(properties)都是支持data binding的 2. binding可以讓UI變得更加靈活 3. UI和...
WPF中的Data Binding調試指南
點擊藍字“大白技術控”關注我喲 加個“星標★”,每日良時,好文必達! WPF中的Data Binding如何Debug? 大家平時做WPF開發,相信用Visual studio的小伙伴比較多。XAML代碼曾經在某些特殊版本的Visual Studio中是可以加斷點進行調試的,不過目前多數版本都不支持在XAML加斷點來調試。 那如果自己需要綁定的 Pr...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...