DataBinding的簡單使用

DataBinding的用法

  • 是時候拋棄ButterKnife,擁抱DataBinding了。 1.ButterKnife對組件化方案支持不如DataBinding 2.ButterKnife只支持View綁定,不支持數據綁定 3.DataBinding是Google出品。 就算只看第三條,你也知道選哪一個了吧 (手動滑稽)下面還有更多DataBinding的優勢

啓用DataBinding

android {
	dataBinding {
		enabled true
		}
}
複製代碼

注意:如在lib中也使用DataBinding也須要在build文件中添加php


DataBinding 的基本使用

數據綁定

咱們建立一個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的子類,生成的ActivityMainBindingButton 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 }。固然,你也能夠導入其餘類。例如定義MyHandlerside

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註解標記該方法,valueStirng[],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就能夠拿到最新的數據了。 ##表達式

  • 數學運算符: + - / * %
  • 字符串拼接: +
  • 邏輯運算符: && ||
  • 二進制: & | ^
  • 一元運算符: +
  • 位運算符: >> >>> <<
  • 比較: == > < >= <=
  • instanceof
  • ()<
  • 數據類型: character, String, numeric, null
  • 類型轉換(ClassCast)
  • 方法回調(Method calls)
  • 數據屬性
  • 數組:[]
  • 三元操做符:? ##與LiveData連用 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
相關文章
相關標籤/搜索