1. 程式人生 > >一步一步教你實現安卓mvvm架構,雙向資料繫結

一步一步教你實現安卓mvvm架構,雙向資料繫結

google 2015年9月推出了mvvm架構,實現了在xml上設定雙向資料繫結,類似js。

開發步驟:

1   首先要先在build.gradle內新增

dataBinding {
    enabled true
}

 

2.  建立一個Model類測試,如下,建立一個user類,帶有三個引數,名字,密碼,頭像

public class User {
    private String name;
    private String password;
    private String avator;

    public User(String name, String password, String avator) {
        this.name = name;
        this.password = password;
        this.avator = avator;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAvator() {
        return avator;
    }

    public void setAvator(String avator) {
        this.avator = avator;
    }
}

3  編寫xml

這裡的xml和之前有不同,首先外面有一層layout標籤,

data中name表示你在MainActivity類中要繫結的資料物件。 type為該物件的完整包路徑

然後如程式碼將你的控制元件和user對應的屬性繫結。

<?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.github.mvvmtest.User"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingVertical="20dp"
        android:orientation="vertical"
        android:gravity="center_horizontal">

        <ImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:header="@{user.avator}"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="@{user.name}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="@{user.password}"/>

    </LinearLayout>

</layout>

4. MainActivity 類

注意幾點, setContentView寫法不一樣了。

新的寫法是:ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

ActivityMainBinding的意思是,比如你的xml叫activity_main,系統編譯時候會幫你生成ActivityMainBinding的類,命名為首字母大寫,去掉下劃線,然後最後加上Binding,把ActivityMainBinding物件和檢視繫結。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        user = new User("張三","123456","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541069934582&di=ae66155eb7cad0d71baa82498539fc52&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201411%2F23%2F20141123205812_Bircn.jpeg");
        binding.setUser(user);
    }

此時執行,發現兩個textview都正常顯示資料了。

你不在需要findviewbyid,也不在需要設定id,也不用寫setText方法了,實現了資料繫結。

5. 接下來我們要改變user的值,然後textview的值也會自動改變,實現雙向資料繫結!

首先修改user類,在變數的get方法加上@Bindable註解,set方法中加入notifyPropertyChanged(BR.name);  BR是系統編譯生成的類,name是你繫結的變數名。只要你加入@Bindable,你的變數就會被系統加入到BR類中。

@Bindable
    public String getName() {
        return name;
    }

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

    @Bindable
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
        notifyPropertyChanged(BR.password);
    }

這樣我們在button事件中修改下user的值看看。

public void clickbutton(View view) {
        tag++;
        if (tag > 3) {
            tag = 0;
        }
        user.setName(names[tag]);
    }

看到沒,只要修改user的model物件,控制元件繫結的值自動改變了!!!是不是很方便。

當然我們也可以在控制元件text前面加上自己的文字,寫法是:

android:text="@{`姓名是:`+user.name}"

6   接下來要做網路載入頭像的資料綁定了 

在user類中加入一個方法

    @BindingAdapter("bind:avator")
    public static void getImage(ImageView view, String url) {
        Glide.with(view.getContext()).load(url).into(view);
    }

注意一定要是靜態方法。

然後在xml繫結到imageview

<ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginTop="20dp"
            android:scaleType="fitXY"
            android:background="@color/colorPrimary"
            app:avator="@{user.avator}"
            />

看效果

出來了吧,資料的雙向繫結!