MVC、MVP的区别和MVVM设计模式及实例
MVVM简介 MVC和MVP的区别
可能你使用过 MVP 设计模式来对代码进行解耦, 但是当前谷歌发布 Data Binding 库来更加简化我们的代码 , 也催生了 MVVM 设计模式在 Android 中的引用 . 在 MVP 中, 我们需要 Model 、 View 、 Presenter 三样进行配合使用 , 但是在 View 中 还是会出现大量的类似 ShowLoad 之类的代码 . 而这次的 MVVM 是由 Model , View , ViewModel 进行配合的 . 其中的区别主要在于
ViewModel , Data Binding 的奇妙之处在于可以将 XML 文件与指定的 JAVA 类绑定 , 实现数据自动更新的效果 .下面来看看结构图:
在 MVVM 设计模式中 , 对于 View 中的数据更新操作都是通过 Data Binding 框架实现的 , 在 Model 发生变化时做出反映 .看看效果图:
依然跟 MVP 的实例一样是一个查询 IP 地址归属地的 Demo .
首先需要打开 Data Binding 绑定功能 , 在 APP 的 build.gradle 文件中添加如下部分
android {
......
dataBinding {
enabled = true
}
.....
}
先来看 XML 文件的变化
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.shire.mvvmdemo.viewModel.MainViewModel"
/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<EditText
android:id="@+id/et_ip"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="IP地址"
/>
<Button
android:id="@+id/btn_search"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/et_ip"
android:onClick="@{viewModel.search}"
android:text="查询"
/>
<TextView
android:id="@+id/tv_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/et_ip"
/>
<ProgressBar
android:id="@+id/pb_load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_search"
android:layout_toStartOf="@id/btn_search"
android:visibility="gone"
style="?android:attr/progressBarStyleSmall"
/>
</RelativeLayout>
</layout>
可以看到 根节点用的是 <layout> 标签 , 并且还出现了一个 <data> 标签 , 在 <data> 标签中还有一个 <variable> 标签 , 在 <variable> 标签中就是我们需要绑定的类以及他的名字 .
这里使用的名字为 viewModel , 绑定的类是 MainViewModel . 至于绑定这个有什么用, 下面会说到 .
再来看看 Activity 文件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setViewModel(new MainViewModel(binding));
}
}
你没看错 , 就是只有这几行代码 ! 其中的 ActivityMainBinding 类是 Data Binding 框架为我们自动生成的 , 这与你的 XML 文件名字相关 , 比如我的 XML 文件名字是 activity_main 那么生成的类就会取消下划线并且在最后加上 Binding 就得到了 ActivityMainBinding . 这个类的实例可以通过 DataBindingUtil.setContentView 来得到 . 这个类里面有我们 XML 文件里所有的控件信息 . 由此 , 也再也不需要去 findViewById 了! 我们先调用了 setViewModel 方法来设置 ViewModel 并且传进去了这个 Binding , 然后我们进入这个 ViewModel 来看看吧 . 界面上的管理目前基本可以全部转移到 ViewModel 中了.
public class MainViewModel implements onSearchListener {
private ActivityMainBinding binding;
private SearchModel searchModel = new SearchModel();
private Handler handler;
public MainViewModel(ActivityMainBinding binding) {
this.binding = binding;
handler = new Handler(Looper.getMainLooper());
}
public void search(View view) {
binding.pbLoad.setVisibility(View.VISIBLE);
searchModel.getIPaddressInfo(binding.etIp.getText().toString().trim(), this);
}
@Override public void onSuccess(final IPAddress ipAddress) {
handler.post(new Runnable() {
@Override public void run() {
binding.pbLoad.setVisibility(View.GONE);
binding.tvMsg.setText(ipAddress.toString());
}
});
}
@Override public void onError() {
handler.post(new Runnable() {
@Override public void run() {
binding.pbLoad.setVisibility(View.GONE);
binding.tvMsg.setText("查询失败");
}
});
}
}
主要看看 search 方法 . 这个方法在 XML 文件中有被绑定到按钮上 , 没注意的可以上去看看 .
binding.pbLoad.setVisibility(View.VISIBLE);
这个就能实现加载动画的显示了! 很方便吧 不需要 findViewById , 然后就是调用 Model 的方法获取需要的信息 , 这里传入了文本编辑框的内容
searchModel.getIPaddressInfo(binding.etIp.getText().toString().trim(), this);
后面拿到了结果之后就通过接口回调对 View 进行了更新 .
@Override public void onSuccess(final IPAddress ipAddress) {
handler.post(new Runnable() {
@Override public void run() {
binding.pbLoad.setVisibility(View.GONE);
binding.tvMsg.setText(ipAddress.toString());
}
});
}
上一篇: MVP模式的简单应用