一、概念
关于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