Android-DataBinding入門系列(一)基本介紹


Google在15年的發布大會上提出了DataBinding數據綁定框架,解決了Android編程的一大痛點。官方原生支持MVVM模型讓我們可以在不改變既有的框架上使用上新的特性。它可以使我們的代碼更加簡潔,不必在頁面中寫太多的findViewById,省時省力。今天我們也體驗了一把,記錄下遇到的問題和簡單的入門介紹下。

1、Android Studio需要更新到 1.3 版本,而且需要開啟DataBinding功能:

在build.gradle配置:

android{
	dataBinding{
		enabled = true
	}
}

2、布局

布局中,根節點要以layout開頭,聲明數據使用data標簽。在data中可以為數據對象聲明變量,引入要使用的類等。
(1)在具體控件中使用對象的數據也挺簡單的,使用@{對象變量.對象屬性}就可以取出數據了;
(2)支持綁定事件:@{對象.方法名(參數)}。
代碼如下:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- DataBinding 現在根節點layout -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 綁定的數據對象 -->
    <data>
        <!-- 為數據對象聲明變量:user,取出屬性的用法:@{user.userName} -->
        <variable
            name="user"
            type="com.ha.cjy.databingdemo.model.UserModel"/>
        <variable
            name="presenter"
            type="com.ha.cjy.databingdemo.MainActivityPresenter"/>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="12dp"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="12dp"
            android:textSize="16sp"
            android:background="@android:color/white"
            android:textColor="@color/colorPrimary"
            android:hint="顯示用戶名"
            android:text="@{user.userName}"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:padding="12dp"
            android:textSize="16sp"
            android:background="@android:color/white"
            android:textColor="@color/colorPrimary"
            android:hint="顯示手機號碼"
            android:text="@{user.telPhone}"
            />
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="12dp"
            android:background="@color/colorPrimary"/>
        <EditText
            android:id="@+id/et_userName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:padding="12dp"
            android:textSize="16sp"
            android:background="@android:color/white"
            android:textColor="@color/colorPrimary"
            android:hint="輸入用戶名"
            />
        <EditText
            android:id="@+id/et_telPhone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:padding="12dp"
            android:textSize="16sp"
            android:background="@android:color/white"
            android:textColor="@color/colorPrimary"
            android:hint="輸入手機號碼"
            />
        <Button
            android:id="@+id/btn_update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:padding="12dp"
            android:textSize="16sp"
            android:background="@color/colorPrimary"
            android:textColor="#FFFFFF"
            android:text="更新數據"
            android:onClick="@{presenter.onClickEvent}"
            />
    </LinearLayout>
</layout>

3、代碼

在ManiActivity中,需要為布局和數據進行綁定操作:DataBindingUtil.setContentView(Activity activity, int layoutId)

package com.ha.cjy.databingdemo;

import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import com.ha.cjy.databingdemo.databinding.ActivityMainBinding;
import com.ha.cjy.databingdemo.model.UserModel;

public class MainActivity extends AppCompatActivity implements MainActivityPresenter{
    //對應的是layout文件名,后綴Binding,這個是自動生成的
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.setPresenter(this);
        UserModel userModel = new UserModel("測試姓名","18012365485");
        binding.setUser(userModel);
    }


    @Override
    public void onClickEvent(View view) {
    	//注意:使用DataBinding,控件的獲取應該使用DataBinding對象,而不是通過findViewById獲取(這樣的方式獲取不到控件的文本內容)
        userModel.setUserName(binding.etUserName.getText().toString());
        userModel.setTelPhone(binding.etTelPhone.getText().toString());

        binding.setUser(userModel);
    }
}

這樣子做,就完成了一個簡單的dataBinding的使用,代碼也比以前簡潔了許多。

但是,看到這里,同學們不禁要問了:“不是說dataBinding的核心功能是實現單向數據綁定呀,沒有看到呀,還是以前取出輸入的文本重新賦值的做法,只是實現形式不一樣而已。”
沒錯,這樣的做法確實沒有體現出單向綁定數據功能。接下來,我們來改造一下代碼。

package com.ha.cjy.databingdemo;

import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.ha.cjy.databingdemo.databinding.ActivityMainBinding;
import com.ha.cjy.databingdemo.model.UserModel;

public class MainActivity extends AppCompatActivity implements MainActivityPresenter{
    //對應的是layout文件名,后綴Binding,這個是自動生成的
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //進行DataBinding綁定
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.setPresenter(this);
        UserModel userModel = new UserModel("測試姓名","18012365485");
        binding.setUser(userModel);
    }

    @Override
    public void onClickEvent(View view) {
        //注意:使用DataBinding,控件的獲取應該使用DataBinding對象,而不是通過findViewById獲取(這樣的方式獲取不到控件的文本內容)
        binding.getUser().setUserName(binding.etUserName.getText().toString());
        binding.getUser().setTelPhone(binding.etTelPhone.getText().toString());
    }
}

看下這句代碼:binding.getUser().setUserName(binding.etUserName.getText().toString());我們使用dataBinding獲取聲明過的User對象,然后為其屬性userName賦值。看到這里,我們也只是看到更改了數據,沒有看到任何更新UI的代碼。不要急,我們接着看一下數據類UserModel的實現就明白了。

package com.ha.cjy.databingdemo.model;

import android.databinding.BaseObservable;
import android.databinding.Bindable;

import com.ha.cjy.databingdemo.BR;

/**
 * 用戶
 * Created by cjy on 17/12/5.
 */

public class UserModel extends BaseObservable {
    /**
     * 用戶名
     */
    //注解 數據變動更新UI更新
    @Bindable
    private String userName;
    /**
     * 手機號碼
     */
    @Bindable
    private String telPhone;

    public UserModel() {
    }

    public UserModel(String userName, String telPhone) {
        this.userName = userName;
        this.telPhone = telPhone;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
        //與@Bindable配合使用,數據有更新,通知UI跟着更新
        notifyPropertyChanged(BR.userName);
    }

    public String getTelPhone() {
        return telPhone;
    }

    public void setTelPhone(String telPhone) {
        this.telPhone = telPhone;
        notifyPropertyChanged(BR.telPhone);
    }
}

由上面代碼中,我們看到了注解Bindable,這個是用來標識屬性是否有變動。官方介紹如下:

The Bindable annotation should be applied to any getter accessor method of an
 * {@link Observable} class. Bindable will generate a field in the BR class to identify
 * the field that has changed.

當然了,只是標識屬性變動是不夠的,這時還是沒有通知UI更新的。我們需要使用notifyPropertyChanged方法,告知UI數據變化了從而更新UI。注意,notifyPropertyChanged方法的參數需要使用BR.屬性名才可以。dataBinding在BR類中為對象屬性生成了唯一的標識碼。

總結

看到這里基礎的入門介紹就講完了,其實還有很多更高級的用法,比如在RecyclerView中怎么用等等,大家可以去自己查閱資料學習,這樣認識的可以更深刻。希望這篇文章對大家能夠有所幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM