Android MVVM小结

Posted 程小白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MVVM小结相关的知识,希望对你有一定的参考价值。

一、概念

关于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

以上是关于Android MVVM小结的主要内容,如果未能解决你的问题,请参考以下文章

Android MVVM在哪里存储数据?

Android 上的 Kotlin:如何在片段中使用数据库中的 LiveData?

Vue学习所得小结

使用Architecture Components构建的应用程序是否使其成为“MVVM”,如果是,应用程序的哪些部分与哪个MVVM层相关?

Android 调用组件 w/listener 或让 viewmodel 调用组件与片段通信

使用 MVVM 和数据绑定更改每个片段中的工具栏标题