Android MVVM架构
1.MVC,MVP,MVVVM
1.1什么是MVVM
1.MVVM,是Model-View-ViewModel的简写,是M-V-VM三部分组成。它本质上就是MVC 的改进 版。MVVM 就是将其中的View 的状态和行为抽象化,其中ViewModel将视图 UI 和业务逻辑分 开,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。
2.MVVM采用双向数据绑定,view中数据变化将自动反映到viewmodel上,反之,model中数据变化 也将会自动展示在页面上。把Model和View关联起来的就是ViewModel。ViewModel负责把Model 的数据同步到View显示出来,还负责把View的修改同步回Model。
3.MVVM核心思想,是关注model的变化,让MVVM框架利用自己的机制自动更新DOM,也就是所 谓的数据-视图分离,数据不会影响视图。
如图(重点):
1.2 Android MVVM
MVVM分为Model,View,ViewModel 三个部分
Model:数据层,包含数据实体和对数据实体的操作,和MVP的model没有区别。
View: 界面层,对应于Activity,XML,负责数据显示以及用户交互。相比MVP的view,这里面的 view视图数据一般是在xml中使用DataBinding进来双向绑定数据的。
ViewModel:关联层,作为中间桥梁 去通知model数据层处理数据业务,并将结果回调给 UI 层处 理 UI 逻辑。ViewModel中只有activity持有vm引用,vm是不持有view的引用的,所以vm的构造方 法中不能传入视图相关的对象。所以重点在于怎么通知view,可以通过观察者回调的方式。但是现 在一般是结合Jetpack来进行view的更新的。
2.MVVM项目框架
如图:
3 MVVM核心构成
3.1 DataBinding (重点)(详细讲解)
数据和UI双向绑定
3.2 LifeCycle
界面生命周期感知
3.3 ViewModel
业务逻辑
3.4 LiveData
可观察数据项
3.5 MVVM项目框架搭建 通用性的快速开发框架 可应用各项目中
4 DataBinding
4.1 DataBinding的简介
1.Data binding 在2015年7月发布的android Studio v1.3.0 版本上引入,在2016年4月Android Studio v2.0.0 上正式支持。目前为止,Data Binding 已经支持双向绑定了,实在2016年的google I/O大会上发布的。现在已经很普及啦,在项目中也在慢慢使用。
2.I/O大会上发布的。现在已经很普及啦,在项目中也在慢慢使用。 Databinding 是一个实现数据和UI绑定的框架,是一个实现 MVVM 模式的工具,有了 Data Binding,在Android中也可以很方便的实现MVVM开发模式。会java web开发的会更好的理解在 xml中绑定数据的模式,在web开发中也是使用@{}来实现数据的显示的。
3.Data Binding 是一个support库,最低支持到Android 2.1(API Level 7+)。使用 DataBing,Gradle的Android Plugin需要在1.5.0-alpha1以上。
4.Data Binding 之前我们不可避免地要编写大量的毫无营养的代码,如 findViewById()、 setText(),setVisibility(),setEnabled() 或 setOnClickListener() 等,通过 Data Binding , 我们可 以通过声明式布局以精简的代码来绑定应用程序逻辑和布局,这样就不用编写大量的毫无营养的代 码了。
缺点:
1. ViewModel与View一一对应;
2. 使用起来灵活性比较低;
3. Model属性发生变化时,ViewDatabinding采用异步更新数据,对于现实大量数据的ListView,会 有一定延迟,在实践测试中发现,Databing效率较低,对于负责的界面不太适用;
4. 自动生成大量代码和属性字段:ViewDataBinding 实现类 DataBinderMapper 等。
4.2使用DataBinding
具体步骤:
1.构建环境(Build Environment)
在build.gradle中添加如下代码:
dataBinding {enabled = true}
2. 数据绑定布局文件
数据绑定的布局文件和我们以前经常写的布局文件稍有不同,并从布局的根标记开始,后面依次是数据 元素和视图根元素,即根布局是 layout,接下来是 data 节点,variable 节点,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="user"type="com.hp.mvvmdemo.model.User" /><variablename="handler"type="com.hp.mvvmdemo.view.activity.MainActivity.Handler" /></data><LinearLayoutandroid:gravity="center"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/tv_show"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!" /><TextViewandroid:layout_marginTop="30dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="20dp"android:text="@{user.username}" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="20dp"android:text="@{user.password}" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="@{()->handler.onClick()}"/></LinearLayout></layout>
3.在MainActivity.java中获取bingding对象
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//setContentView(R.layout.activity_main);ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);}
4.4databinding点击事件
xml:
activity:
5.单向绑定
5.1单个值的绑定:
1.集成DataDinding 添加 dataBinding.enabled true 和 dataBinding { enabled = true }
android {
....
dataBinding {
enabled = true
}
}
2.实现xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data><variablename="title"type="java.lang.String" />
</data>
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:textColor="#000000"android:id="@+id/tvTitle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{title}"/>
</LinearLayout>
</layout>
5.2对象的绑定:
1.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data><variable name="user" type="com.example.User"/>
</data>
<LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.firstName}"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
2.实体类:
public class User {private final String firstName;private final String lastName;public User(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public String getFirstName() {return this.firstName;}public String getLastName() {return this.lastName;}
}
3.databinding:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);MainActivityBinding binding = DataBindingUtil.setContentView(this,R.layout.main_activity);User user = new User("Test", "User");binding.setUser(user);}
6.双向绑定
双向绑定是指其中任意一个变化后都会同步更新到另一个。双向绑定使用@={}表达式来实现 4.5.1 目前已经支持双向绑定的列表
7.从网页获取图片
整体架构:
导入要使用的依赖:
build.gradle
implementation 'com.squareup.picasso:picasso:2.71828'//for rxjavaimplementation 'io.reactivex.rxjava2:rxjava:2.2.6'//for rxandroidimplementation 'io.reactivex.rxjava2:rxandroid:2.1.1'//衔接 Retrofit & RxJava,此处一定要注意使用RxJava2的版本implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'//添加Retrofit依赖implementation 'com.squareup.retrofit2:retrofit:2.5.0'//添加Gson解析implementation 'com.squareup.retrofit2:converter-gson:2.5.0'//添加图片加载库依赖implementation 'com.github.bumptech.glide:glide:4.12.0'
xml层:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="imgurl"type="String" /><variablename="localurl"type="int" /><variablename="mainviewmodel"type="com.hp.day48stage01.viewmodel.MainViewModel" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".view.activity.MainActivity"><ImageViewapp:netImage="@{imgurl}"app:localImage="@{localurl}"android:id="@+id/imageView"android:layout_width="300dp"android:layout_height="300dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/ic_launcher_background" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="64dp"android:text="点击见美女"android:onClick="@{()->mainviewmodel.onChange()}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="@+id/imageView"app:layout_constraintHorizontal_bias="0.495"app:layout_constraintStart_toStartOf="@+id/imageView"app:layout_constraintTop_toBottomOf="@+id/imageView"app:layout_constraintVertical_bias="0.029" /></androidx.constraintlayout.widget.ConstraintLayout>
</layout>
编写实体类:
ModelGril.java
public class ModelGirl {private boolean success;private String imgurl;private Info info;@Overridepublic String toString() {return "MobileGirl{" +"success=" + success +", imgurl='" + imgurl + '\'' +", info=" + info +'}';}public boolean isSuccess() {return success;}public void setSuccess(boolean success) {this.success = success;}public String getImgurl() {return imgurl;}public void setImgurl(String imgurl) {this.imgurl = imgurl;}public Info getInfo() {return info;}public void setInfo(Info info) {this.info = info;}public static class Info{private int width;private int height;private String type;public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public String getType() {return type;}public void setType(String type) {this.type = type;}}}
编写网络接口:
public interface GetImage_Interface {@GET("api/mobil.girl?type=json")Observable<ModelGirl> getPic();
}
适配器:
public class ImageBindingAdapter {@BindingAdapter(value = {"netImage","localImage"},requireAll = false)public static void setImage(ImageView imageView,String url,int path){if (url != null && !"".equals(imageView)) {/*Glide.with(imageView.getContext()).load(url).override(300,300).centerCrop().into(imageView);*/Picasso.get().load(url).placeholder(R.mipmap.jiazai).into(imageView);}else {imageView.setImageResource(path);}}}
MainViewModel
public class MainViewModel {private String imgurl;private ModelGirl modelGirl;private ActivityMainBinding binding;private final String TAG = "MainViewModel";public ModelGirl getModelGirl() {return modelGirl;}public void setModelGirl(ModelGirl modelGirl) {this.modelGirl = modelGirl;}public MainViewModel() {}public MainViewModel(ActivityMainBinding binding,String imgurl) {this.binding = binding;this.imgurl = imgurl;initGirl();}private void initGirl() {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.vvhan.com/").addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();GetImage_Interface request = retrofit.create(GetImage_Interface.class);Observable<ModelGirl> observable = request.getPic();observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<ModelGirl>() {@Overridepublic void accept(ModelGirl modelGirl) throws Exception {Log.i(TAG,"连接成功");//Log.i(TAG, modelGirl.toString());imgurl = modelGirl.getImgurl();binding.setImgurl(imgurl);}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Log.i(TAG,"连接失败");}});}public void onChange(){initGirl();}
}
MainActivity:
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);binding.setMainviewmodel(new MainViewModel(binding,""));}
}
Android MVVM架构相关推荐
- Android MVVM 架构应用实现
以前项目中虽然也使用MVVM架构,但由于整体框架不是我自己搭建的,导致我对于MVVM架构的整体还是很不熟悉,所以这次就自己搭建并实现一次MVVM架构. MVVM架构使用的组件有ViewModel.Li ...
- Android MVVM架构设计模式,从DataBinding开始
MVVM在android端已经出了很久了,但是还是比较少使用到,现在写Android架构设计的时候比较多使用的是MVP,以前在用Angularjs和Vue接触过双向数据绑定的使用和思想,所以看到MVV ...
- android mvvm架构-基于Jetpack
2020年最新最实用的android-MVVM框架 https://github.com/VcStrong/JetpackMVVM.git 注册的密码规则是数字加字母超过8位即可 测试账号:13126 ...
- android组件化架构 书,Android MVVM组件化架构方案
MVVMHabitComponent 关于Android的组件化,相信大家并不陌生,网上谈论组件化的文章,多如过江之鲫,然而一篇基于MVVM模式的组件化方案却很少.结合自身的调研和探索,在此分享一篇基 ...
- android mvvm livedata_再谈Android应用架构——Jetpack VS 生命周期
前面我们对MVC.MVP.MVVM进行了详尽的分析,但还有一个问题悬而未决,那就是生命周期.在Android平台上生命周期具有十分重要的意义,因此这也是架构必须考虑的因素之一.生命周期处理不好很容易发 ...
- 《Android构建MVVM》系列(一) 之 MVVM架构快速入门
前言 本文属于<Android构建MVVM>系列开篇,共六个篇章,详见目录树. 该系列文章旨在为Android的开发者入门MVVM架构,掌握其基本开发模式. 辅以讲解Android Arc ...
- android数据流分类,【Android工程之类】1 MVVM架构 - MVVM与单向数据流
前言 这个系列将讲述使用MVVM架构.LiveData.Room.Kodein.Retrofit.EventBus来建立一个统一的.优雅的.可维护的TODO程序,本系列分为多个章节,从0开始一步一步引 ...
- Android的MVVM架构的单Activity应用实践
前言 谈Android架构大家很容易想到MVC.MVP和MVVM. 1.MVC 首先分析一下上面各层之前对应的Android代码,layout.xml里面的xml文件就对应于MVC的view层,里面都 ...
- 一个 Android MVVM 组件化架构框架
模块 app: app壳 工程,是依赖所有组件的壳,该模块不应该包含任何代码,它只作为一个空壳存在,由于项目中使用了EventBusAPT技术,需要索引到各业务组件的对应的APT生成类,所以在 app ...
最新文章
- oracle查看临时表空间文件,Oracle-临时表空间
- 计算机语言学习app,学习之编程语言
- Android__Context
- 求一个数字是几位数(简便)
- 大蜘蛛序列号_没事校个色?Datacolor Spyder5 Elite红蜘蛛五代校色仪体验
- 数据结构与算法系列----字典树
- pycharm导出依赖包_使用pycharm导出虚拟环境依赖包
- Axure RP 8 注册码
- C语言程序设计精髓--第3周编程题在线测试
- int[]是什么类型?
- 马斯洛需求层次与产品的关系
- android之使用QQ互联实现qq账号登录App
- 计算机考研二战有必要吗,2019计算机考研二战的小伙伴要调整注重的几点
- 从Siri到Mobile AI,华为人工智能突击苹果
- 日期格式的正则表达式
- SaaSBase:AdsPower是什么?
- 机械原理程序设计c语言,C语言机械原理编程,连杆运动分析图线.docx
- 计算机科学精彩帖子收集--JAVA和分布式专栏
- 自动化运维平台Spug介绍
- 什么是项目合同管理?
热门文章
- 贵阳 计算机就业,学计算机专业就业率高值得信赖_贵阳经济技术学校
- WhatsApp客服系统,为什么使用SendWS拓客系统实现WhatsApp客服系统多账号管理?
- iOS仿微信聊天输入框、评论输入框
- 不可不知的银行业务知识-整理版
- Android Studio 获取经纬度
- ios运行html时黑屏,iOS13 ,xcode11新建项目真机运行出现黑屏及新出现的SceneDelegate的作用...
- window.showModalDialog不兼容的解决方案
- CPU卡加密系统与M1加密系统比较!
- 为什么数据治理如此重要
- 列表4:拼接排序方法实操