目前google的databinding library還處在rc版,其中編譯器發揮了主要做用。目前也只是在android studio開發環境中支持。java
mvvm可以大大下降模塊間的耦合度,在開發過程當中更容易控制數據傳遞,性能方面也有所長,傳統findViewById要遍歷整個樹的children。android
它的編譯過程:app
1. 首先會去檢查layout下的視圖文件,將其中全部關於databinding的元素所有刪除、替換(這一過程所有由編譯器來完成,能夠搜索下build文件夾視圖文件),由於這些標籤根本沒法識別。mvvm
2. 第二步解析表達式語法,如三目運算。ide
3. 第三步解析綁定值,對應java code中的含義。性能
4. 第四步會生產databinding class文件,這些文件由編譯器自動生成。gradle
因爲它是預編譯的,沒有了運行時的反射提升了性能,但並不能真正體現view層和behind層的分離,當咱們在view層指定了一個java code中不存在的屬性,這時候編譯將不會經過。ui
新建projectthis
引入類庫google
經過android sdk manager下載android support respository。build.gradle(Moudle:app)加入定義:
android {
....
dataBinding {
enabled = true
}
}
添加viewmodel
這裏提供視圖數據,至關於shh中service層吧,主要放置屬性、集合和事件方法。
1 package com.example.mymvvm.viewmodel; 2 3 import android.databinding.BaseObservable; 4 5 import com.example.mymvvm.model.*; 6 7 public class MainViewModel extends BaseObservable { 8 9 public MainViewModel() { 10 this.Init(); 11 } 12 13 // attribute 14 private User user; 15 16 public User getUser() { 17 return user; 18 } 19 20 public void setUser(User user) { 21 this.user = user; 22 } 23 24 // method 25 public void Init() { 26 this.user = new User(); 27 this.user.setName("who are u"); 28 } 29 30 // command 31 public void SubmitCommand(android.view.View view) { 32 this.user.setName("hello world"); 33 } 34 }
user類
@Bindable註解,編譯時會在BR中生產BR.name,BR做用就是至關於一個觀察者,而不會去監視整個project資源。
添加notifyPropertyChanged,當name值改變,可以及時通知到UI界面。
1 package com.example.mymvvm.model; 2 3 import android.databinding.BaseObservable; 4 import android.databinding.Bindable; 5 6 public class User extends BaseObservable { 7 8 @Bindable 9 private String name; 10 11 public void setName(String name) { 12 this.name = name; 13 notifyPropertyChanged(com.example.mymvvm.BR.name); 14 } 15 16 public String getName() { 17 return name; 18 } 19 }
註冊viewmodel
這裏創建和view試圖對應關係,編譯時會自動檢測binding元素。
ActivityMainBinding會自動根據active_main.xml視圖生產,注意名稱對應。
1 package com.example.mymvvm; 2 3 import android.databinding.DataBindingUtil; 4 import android.support.v7.app.AppCompatActivity; 5 import android.os.Bundle; 6 7 import com.example.mymvvm.viewmodel.*; 8 import com.example.mymvvm.databinding.ActivityMainBinding; 9 10 public class MainActivity extends AppCompatActivity { 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 16 binding.setMainViewModel(new MainViewModel()); 17 } 18 }
添加view
1 <?xml version="1.0" encoding="utf-8"?> 2 <layout xmlns:android="http://schemas.android.com/apk/res/android"> 3 <data> 4 <variable name="mainViewModel" type="com.example.mymvvm.viewmodel.MainViewModel" /> 5 </data> 6 7 <LinearLayout android:orientation="vertical" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent"> 10 <TextView android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:text="@{mainViewModel.User.name}" /> 13 <Button android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:text="submit" 16 android:onClick="@{mainViewModel.SubmitCommand}"/> 17 </LinearLayout> 18 </layout>
結果
當點擊submit按鈕,觸發command事件。
android studio編譯器最大程度下降了代碼的複雜性,編譯器作了不少幕後工做,能夠看下build後的文件。
得益於INotifyPropertyChanged,INotifyPropertyChanging接口,微軟反而在mvvm這塊顯得更加簡潔有力。