1. 程式人生 > >Android DataBinding全解析,你該用這個框架了

Android DataBinding全解析,你該用這個框架了

前言:

Data binding 在2015年7月釋出的Android Studio v1.3.0 版本上引入,在2016年4月Android Studio v2.0.0 上正式支援。目前為止,Data Binding 已經支援雙向綁定了。

Databinding 是一個實現資料和UI繫結的框架,在這之前,我們不可避免地要編寫大量的毫無營養的程式碼,如 findViewById()、setText(),setVisibility(),setEnabled() 或 setOnClickListener() 等,通過 Data Binding , 我們可以通過宣告式佈局以精簡的程式碼來繫結應用程式邏輯和佈局,提高開發效率、

雖然也有ButterKnife,RoboBinding等,但是DataBinding效能高,功能全。所以不用猶豫,在你的專案中用吧。
谷歌的官方文件

主要優勢:

1.去除Activity和Fragment中無用的UI程式碼
2.效能超過手寫程式碼(不會用id出錯crash)
3.保證執行在主執行緒中。

整合:

首先保證自己的AS版本是2.0以上,然後在專案的gradle中新增,然後編譯下。

android {
    ...
    dataBinding{
        enabled=true;
    } 
    ...
}

使用方法:

1.在佈局檔案中,最外面套一層layout標籤。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <RelativeLayout

        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height
="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.young.databindingdemo.MainActivity">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!"/> </RelativeLayout> </layout>

2。activity中獲取:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //添加布局,ActivityMainBinding命名方式是根據佈局檔案的命名方式來的
        ActivityMainBinding binding= DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
        //直接取到了id為tv_hello的textview標籤
        binding.tvHello.setText("data Binding");
    }
}

以上只是簡單的去除findviewbyid獲取空間的用法,但是dataBinding的強大之處遠不止於此。

XML中資料繫結:

1.我們先新建一個實體javabean類User

public class User {
    private String name;
    private int age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public User(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
}

2.來看我們如何在xml中新增實體資料:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="user"
            type="com.young.databindingdemo.data.User"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="12dp"
            android:text="@{user.name}"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="12dp"
            android:text="@{user.age}"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="12dp"
            android:text="@{user.sex}"/>

    </LinearLayout>
</layout>

可以看到

   <data>
        <variable
            name="user"
            type="com.young.databindingdemo.data.User"/>
    </data>

data標籤將資料引用啟用,name是自己定義的物件的名字,type是類的全路徑
也可以寫成如下的形式:

<data>
  <import type="com.young.databindingdemo.data.User" alias="myUser"/>
        <variable
            name="user"
            type="User"/>
</data>

所以type也是可以寫成String,int ArrayList等形式。alias防止包名一樣。
3.我們來看Activity中如何使用:

public class DataActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityDataBinding binding= DataBindingUtil.setContentView(DataActivity.this, R.layout.activity_data);
        binding.setUser(new User("young","male",25));
    }
}

這樣資料就會顯示,Activity中無需寫settext程式碼。

XML事件繫結:

事件繫結有兩種方式,先看第一中,方法引用,特點:自定義一個類,定義一個方法,方法中的引數和要繫結的事件引數一致。textview點選事件如下:

listener事件類:

public class handleClick {
    public void OnClickHandle(View view){
        Log.i("ssssss","click");
    }
}

layout:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="click"
            type="com.young.databindingdemo.handleClick"/>
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_hello"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{click.OnClickHandle}"
            android:gravity="center"
            android:text="data binding"
            android:background="#0f0"
            android:padding="12dp"/>
    </LinearLayout>
</layout>

要注意data的資料引用和onClick中點選事件的寫法,方法一定不要加()。另一種寫法為:android:onClick=”@{click::OnClickHandle}”

activity程式碼:
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //添加布局,ActivityMainBinding命名方式是根據佈局檔案的命名方式來的
    ActivityMainBinding binding= DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
    //直接取到了id為tv_hello的textview標籤
    binding.setClick(new handleClick());
}

}
注意:data中引用的外部資料一定都要在Activity中set進去。

點選事件第二種方式:監聽器繫結。
與第一種方法類似,但是這種方式可以設定自己的方法引數
如:

public class handleClick {
    //方法引用
    public void OnClickHandle(View view){
        Log.i("ssssss","click");
    }
    //監聽器繫結
    public void OnClickHandle2(){
        Log.i("ssssss","click2");
    }
}

layout的寫法也有區別:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="click"
            type="com.young.databindingdemo.handleClick"/>
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_hello"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{click::OnClickHandle}"
            android:gravity="center"
            android:text="clikc1"
            android:background="#0f0"
            android:padding="12dp"/>
        <TextView
            android:id="@+id/tv_hello2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->click.OnClickHandle2()}"
            android:gravity="center"
            android:background="#00f"
            android:text="clikc2"
            android:padding="12dp"/>
    </LinearLayout>
</layout>

可以看到,就是onClick的寫法區別,整體是一個lambda寫法,方法要完整。

XML中支援邏輯判斷

比如:

  <TextView
            android:id="@+id/tv_hello3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text='@{1>2?"3":"5"}'
            android:background="#f00"
            android:padding="12dp"/>

注意:text不支援int型別,所以3和5要是String型別才行。
下面我們就來看看錶達式支援的一下語法和不支援的語法
支援的表示式:
Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <=
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:

不支援的表示式:
this
super
new
Explicit generic invocation

null檢查

DataBinding會自動null的判斷,比如我們定義的User類,如果引用的user.age沒有賦值,會有預設值,不會因為null而crash。

以上只是DataBinding的小試牛刀,很多高階的功能歡迎click下篇文章。