一、概念
關於MVC、MVP與MVVM的概念就不介紹了,總之一句話,MVVM概念出現比MVP早,MVP比MVC早,作為程序員就應該去學習最新的技術不是?詳細的概念介紹移步這里吧,https://www.jianshu.com/p/4830912f5162
二、MVVM的使用辦法
第一步:在工程的build.gradle中配置
1 dataBinding{ 2 enabled = true 3 }
第二步:修改布局文件,記得布局文件一定要用layout標簽給括起來,下面先把布局文件都貼出來
1 <?xml version="1.0" encoding="utf-8"?> 2 <layout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:bind="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools"> 6 7 <data> 8 <variable 9 name="user" 10 type="com.plbear.doncal.rxjavademo.User"></variable> 11 12 <variable 13 name="clickHandler" 14 type="com.plbear.doncal.rxjavademo.MainActivity.ClickHandler"></variable> 15 </data> 16 17 <android.support.constraint.ConstraintLayout 18 android:layout_width="match_parent" 19 android:layout_height="match_parent"> 20 21 <TextView 22 android:id="@+id/lab_name" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:layout_marginLeft="63dp" 26 android:layout_marginStart="63dp" 27 android:layout_marginTop="46dp" 28 android:text="@{user.name}" 29 app:layout_constraintStart_toStartOf="parent" 30 app:layout_constraintTop_toBottomOf="@+id/button" /> 31 32 <Button 33 android:id="@+id/button" 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content" 36 android:layout_marginLeft="63dp" 37 android:layout_marginStart="63dp" 38 android:layout_marginTop="26dp" 39 android:onClick="@{clickHandler.btnClickHandler}" 40 android:text="Button" 41 app:layout_constraintStart_toStartOf="parent" 42 app:layout_constraintTop_toTopOf="parent" /> 43 44 <TextView 45 android:id="@+id/lab_passwd" 46 android:layout_width="wrap_content" 47 android:layout_height="wrap_content" 48 android:layout_marginTop="28dp" 49 android:text="@{user.passwd}" 50 app:layout_constraintStart_toStartOf="@+id/lab_name" 51 app:layout_constraintTop_toBottomOf="@+id/lab_name" /> 52 53 </android.support.constraint.ConstraintLayout> 54 </layout>
從這個布局文件中,我們看到定義了兩個變量,分別是user和clickHandler,其中,在兩個TextView文件中,分別用以下的辦法來來使用:
1 android:text="@{user.name}"
1 android:onClick="@{clickHandler.btnClickHandler}"
第二步:Java文件的修改
新增一個User數據類
1 public class User { 2 public ObservableField<String> name = new ObservableField<>(); 3 public ObservableField<String> passwd = new ObservableField<>(); 4 }
MainActivity的代碼及解釋如下:
1 package com.plbear.doncal.rxjavademo; 2 3 import android.databinding.DataBindingUtil; 4 import android.support.v7.app.AppCompatActivity; 5 import android.os.Bundle; 6 import android.view.View; 7 8 import com.plbear.doncal.rxjavademo.databinding.ActivityMainBinding; 9 10 public class MainActivity extends AppCompatActivity { 11 ActivityMainBinding binding; //自動生成ActivityMainBinding類,命名規則是布局文件使用駝峰規則來命名 12 final User mUser = new User(); 13 14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 binding = DataBindingUtil.setContentView(this,R.layout.activity_main); 18 mUser.name.set("plbear"); //修改變量 19 mUser.passwd.set("123456"); 20 binding.setUser(mUser);//設置layout文件中的user值 21 // binding.setClickHandler(new ClickHandler());//2.設置layout文件中的clickHandler值 22 binding.button.setOnClickListener(v ->{ 23 mUser.passwd.set("change name too"); //1.可以用這種方式設置點擊事件,點擊后password被設置為change name too 24 }); 25 } 26 27 //2.也可以用這種方式設置點擊事件,點擊之后,name控件中的值變為 change name 28 //設置前需要在前面設置binding.setClickHandler 29 // public class ClickHandler{ 30 // public View.OnClickListener btnClickHandler = v -> { 31 // mUser.name.set("change name"); 32 // }; 33 // } 34 }
三、換一種實現
前面利用ObservableFiled來實現,這種實現方式比較適合於細粒度的實現,但是一旦大量的數據都是通過MVVM的方式來做,這種實現顯然是不合時宜的。那就再找一種數據類的實現方式:
1 package com.plbear.doncal.rxjavademo; 2 3 import android.databinding.BaseObservable; 4 import android.databinding.Bindable; 5 import android.databinding.ObservableField; 6 7 public class User extends BaseObservable{ 8 @Bindable 9 private String name; 10 11 @Bindable 12 private String passwd; 13 14 public void setPasswd(String passwd){ 15 this.passwd = passwd; 16 notifyPropertyChanged(BR.passwd); 17 } 18 19 public void setName(String name){ 20 this.name = name; 21 notifyPropertyChanged(BR.name); 22 } 23 24 public String getName(){ 25 return this.name; 26 } 27 28 public String getPasswd(){ 29 return this.passwd; 30 } 31 }
這里有兩個坑需要注意下:
- Bindable標簽,這個標簽可以用在變量上面,也可以用在getName和getPasswd上面
- notifyPropertyChanged的時候,一定要通知到Br.passwd,而不是BR.user