一步一步教你實現安卓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}"
/>
看效果
出來了吧,資料的雙向繫結!