android {
dataBinding {
enabled true
}
}
複製代碼
注意:如在lib中也使用DataBinding也須要在build文件中添加php
咱們建立一個User類,User有兩個屬性:name和age。java
public class User {
private String name;
private int age;
public User() {
this.name = "小花";
this.age = 18;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
複製代碼
也能夠這樣寫android
public class User {
public String name;
public int age;
}
複製代碼
而後咱們想把User這個對象的兩個屬性綁定在xml控件中,咱們建立一個activity_main.xml文件.由於age屬性是int類型,而textView.setText()不容許使用int,因此,咱們能夠在後面拼上字符標誌``
。git
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.ding.databindingdemo.User" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.age+`歲`}" />
</LinearLayout>
</layout>
複製代碼
而後咱們在Activity中獲取xml對應的DataBinding對象,並對其進行賦值github
private ActivityMainBinding mBinding;//這個對象是根據activity_main.xml命名規則自動生成的,繼承自ViewDataBindig了;類
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
mBinding.setVariable(BR.user,new User());
//或者
mBinding.setUser(new User());
mBinding.executePendingBindings();
}
複製代碼
fragment這樣綁定DataBindingUtil.inflate(inflater,R.layout.fragment_home,container,false);
數組
是否是很簡單?這還簡單的,看的我頭皮發麻,兩眼發暈,我不須要綁定什麼數據,我就想跟ButterKnife用法同樣。好,下面就知足你 ###控件綁定 咱們在xml中爲每一個你須要拿到的控件命名ID架構
<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" />
複製代碼
那咱們應該怎麼拿到對應的控件呢?就是咱們的ViewDataBinding
的子類,生成的ActivityMainBinding
中Button mBinding.mainBtn
(生成規則遵循Java駝峯命名),這樣咱們就能夠拿到這個按鈕了,以後的事情就不用我說了把。 ##方法綁定app
<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick"/>
複製代碼
之前咱們能夠這樣寫點擊事件,而後在activity中定義public void onClick(View view) { }
方法,而後在這裏面對點擊事件進行處理。如今,咱們能夠對這個點擊事件作任何方法的跳轉。傳入類,mBinding.setVariable(BR.act,this);
而後傳入類方法android:onClick="@{()->類對象.類方法(參數para)}"
框架
<variable name="act" type="com.example.ding.databindingdemo.MainActivity"/>
<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{()->act.getName(user.name)}"/>
複製代碼
咱們在activity中定義的方法public void getName(String name){ //todo }
。固然,你也能夠導入其餘類。例如定義MyHandlers
ide
public class MyHandlers {
public void getName(String name) { ... }
}
複製代碼
佈局文件就要這樣寫。
<variable name="handler" type="com.example.ding.databindingdemo.MyHandlers"/>
<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{()->handler.getName(user.name)}"/>
複製代碼
注意:要在Activity
中傳入MyHandlers
實例,否則會報空指針。 ##自定義方法Binding adapters 有些控件不能直接傳數據就能展現,例如ImageView
,RecyclerView
之類。咱們能夠用BindingAdapter
註解來自定義方法,xml中使用方式:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" bind:imageUrl="@{user.pic}" />
複製代碼
新建一個java類,類名隨意。類方法需爲static
,@BindingAdapter
註解標記該方法,value
傳Stirng[]
,xml中使用的atts與裏面的命名規則一致。requireAll
是否必須傳。而後在setImageUrl
方法中獲取view和url參數,而後進行展現。固然url也能夠替換爲src或者bitmap
public class ImageBindingAdapter {
@BindingAdapter(value = {"bind:imageUrl"},requireAll = true)
public static void setImageUrl(ImageView view,String url){
Glide.with(view.getContext()).load(url).into(view);
}
@BindingAdapter(value = {"bind:imageSrc"},requireAll = true)
public static void setImageSrc(ImageView view,int src){
view.setImageResource(src);
}
@BindingAdapter(value = {"bind:imageBitmap"},requireAll = true)
public static void setImageBitmap(ImageView view,Bitmap bitmap){
view.setImageBitmap(bitmap);
}
}
複製代碼
假如你寫了一個自定義控件,你也能夠用@BindingAdapter
綁定你的數據源。例如,我寫了一個MyLinearLayout
來實現ListView
,而後我寫了一個text_list方法來傳遞數據。
<com.ding.example.MyLinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" bind:text_list="@{user.datas}" />
複製代碼
java代碼
public class LinearLayoutBindingAdapter {
@BindingAdapter(value = {"bind:text_list"},requireAll = true)
public static void setDataResource(MyLinearLayout layout,List datas){
layout.setDataList(datas);
}
複製代碼
這樣,咱們就把數據源傳到咱們的MyLinearLayout
中,而後在咱們自定義的LinearLayout
中對數據作處理了。 ##雙向綁定 雙向綁定使用@={}
就能夠實現了。沒錯,就是這麼簡單。例如,EditText
中雙向綁定了user.job
這個屬性,當editText
中內容發生更改時,綁定的數據user.job
也會更新,經過mBinding.getUser().job
就能夠拿到最新的數據了。 ##表達式
LiveData
是谷歌新推出的一個可被觀察的數據持久化的控件,一般出如今ViewModel中,是用用MVVM架構。有興趣的看一下個人上一篇文章基於Google MVVM框架的baseMVVM框架。 LiveData
遵循其餘應用程序控件的生命週期,例如Activity,Fragment或Service。此感知確保LiveData
僅更新處於活動生命週期狀態的應用程序控件觀察者,不會形成內存泄漏。具體是用請參考官方文檔。DataBinding
需調用setLifecycleOwner(LifecycleOwner lifecycleOwner)
以後,綁定了LiveData
數據源的xml控件纔會隨着數據變化而改變。LiveData
暴露公開兩個方法用於設置值: 1.postValue
:容許後臺線程向主進程推送數據 2.setValue
:只容許在主線程調用,若是在其餘線程調用會報錯:This method must be called from the main thread
最後奉上demo的github地址 https://github.com/dingdaidao/DataBindingDemo