MVC、MVP的区别和MVVM设计模式及实例
来源:互联网 发布:淘宝海景房图片怎么做 编辑:程序博客网 时间:2024/05/16 18:12
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()); } }); }
- MVC、MVP的区别和MVVM设计模式及实例
- MVVM模式及与MVP和MVC的区别
- MVC,MVP 和 MVVM 的图示及mvp设计模式架构设计图
- MVP、MVVM,MVC设计模式的实例分析
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 理解MVC,MVP和MVVM设计模式
- 设计模式-MVC,MVP 和 MVVM
- 浅谈MVC、MVP、MVVM架构模式的区别和联系
- 浅谈MVC、MVP、MVVM架构模式的区别和联系
- 浅谈MVC、MVP、MVVM架构模式的区别和联系
- 下拉框联动省市js方法
- 算法之帕斯卡三角形
- Python薪资又涨了,这可咋办啊!
- [duyi]171130 继承、枚举、克隆
- 正则表达式匹配(字符串)
- MVC、MVP的区别和MVVM设计模式及实例
- Android给RecyclerView添加头(Header)和尾(Footer)和分标题(Title)——最简单的两种方法
- CCF 201612-2 工资计算
- todomvp的简化版本
- 微信小程序实现图片懒加载的懒办法(思路参考)
- nginx使用stream反向代理mysql
- 【笔记】Java代码调用exe
- vue-cli构建项目
- ios借贷类马甲包