Android MVP模式实战教程
一、什么是mvp
在网上找了些资料,整理如下:
mvp是模型(model)、视图(view)、主持人(presenter)的缩写,分别代表项目中3个不同的模块。
模型(model):负责处理数据的加载或者存储,比如从网络或本地数据库获取数据等;
视图(view):负责界面数据的展示,与用户进行交互;
主持人(presenter):相当于协调者,是模型与视图之间的桥梁,将模型与视图分离开来。
如下图所示,view与model并不直接交互,而是使用presenter作为view与model之间的桥梁。其中presenter中同时持有viwe层以及model层的interface的引用,而view层持有presenter层interface的引用。当view层某个界面需要展示某些数据的时候,首先会调用presenter层的某个接口,然后presenter层会调用model层请求数据,当model层数据加载成功之后会调用presenter层的回调方法通知presenter层数据加载完毕,最后presenter层再调用view层的接口将加载后的数据展示给用户。这就是mvp模式的整个核心过程。
在mvp模式里通常包含4个要素:
(1)view:负责绘制ui元素、与用户进行交互(在android中体现为activity);
(2)view interface:需要view实现的接口,view通过view interface与presenter进行交互,降低耦合,方便进行单元测试;
(3)model:负责存储、检索、操纵数据(有时也实现一个model interface用来降低耦合);
(4)presenter:作为view与model交互的中间纽带,处理与用户交互的负责逻辑。
二、mvp模式的使用
上面一张简单的mvp模式的uml图,从图中可以看出,使用mvp,至少需要经历以下步骤:
1.创建ipresenter接口,把所有业务逻辑的接口都放在这里,并创建它的实现presentercompl(在这里可以方便地查看业务功能,由于接口可以有多种实现所以也方便写单元测试)
2.创建iview接口,把所有视图逻辑的接口都放在这里,其实现类是当前的activity/fragment
3.由uml图可以看出,activity里包含了一个ipresenter,而presentercompl里又包含了一个iview并且依赖了model。activity里只保留对ipresenter的调用,其它工作全部留到presentercompl中实现
4.model并不是必须有的,但是一定会有view和presenter
三、一个简单的mvp示例
实现一个简单的用户登录
效果如下:
先来看看java文件的目录结构:
1.baen包
userbean
package com.example.mvpe.bean; /** * created by fendo on 2017/4/29. */ public class userbean { private string username; private string userpwd; public userbean() { } public userbean(string username, string userpwd) { this.username = username; this.userpwd = userpwd; } public string getusername() { return username; } public void setusername(string username) { this.username = username; } public string getuserpwd() { return userpwd; } public void setuserpwd(string userpwd) { this.userpwd = userpwd; } }
2.model包
iusermodel类
package com.example.mvpe.model; import com.example.mvpe.bean.userbean; /** * created by fendo on 2017/4/29. */ public interface iusermodel { void setsid(int cid); userbean load(int sid); void setusername(string username); void setuserpwd(string userpwd); }
usermodelimp类
package com.example.mvpe.model; import android.provider.settings; import android.util.log; import android.util.sparsearray; import com.example.mvpe.bean.userbean; /** * created by fendo on 2017/4/29. */ public class usermodelimp implements iusermodel{ private static final string activity_tag="usermodelimp"; private string username; private string userpwd; private int sid; private sparsearray<userbean> su=new sparsearray<userbean>(); @override public void setsid(int cid) { sid=cid; } @override public userbean load(int sidy) { sid=sidy; userbean ub=su.get(sid,new userbean("not found", "not found")); return ub; } @override public void setusername(string usernamey) { username=usernamey; } @override public void setuserpwd(string userpwdy) { userpwd=userpwdy; userbean usb=new userbean(username,userpwd); system.out.print(username+"----"+userpwd+"----"+sid); log.d(usermodelimp.activity_tag, "start_ok"+username+"----"+userpwd+"----"+sid); su.append(sid,usb); } }
3.persenter包
userpersenter类
package com.example.mvpe.presenter; import android.util.log; import android.view.view; import com.example.mvpe.bean.userbean; import com.example.mvpe.model.iusermodel; import com.example.mvpe.model.usermodelimp; import com.example.mvpe.view.iuserview; /** * created by fendo on 2017/4/29. */ public class userpersenter { private static final string activity_tag="userpersenter"; private iuserview iuserview; private iusermodel iusermodel; public userpersenter(iuserview view){ iuserview=view; iusermodel=new usermodelimp(); } public void saveuser(int sid,string username,string userpwd){ iusermodel.setsid(sid); iusermodel.setusername(username); iusermodel.setuserpwd(userpwd); } public void loaduser(int sid){ userbean usb=iusermodel.load(sid); log.d(activity_tag, "loaduser: "+usb.getusername()); iuserview.setusername(usb.getusername()); iuserview.setuserpwd(usb.getuserpwd()); } }
4.view包
iuserview类
package com.example.mvpe.view; import com.example.mvpe.bean.userbean; /** * created by fendo on 2017/4/29. */ public interface iuserview { int getid(); void setusername(string username); void setuserpwd(string userpwd); string getuserpwd(); string getusername(); }
useractivity类
package com.example.mvpe.view; import android.app.activity; import android.os.bundle; import android.view.view; import android.widget.button; import android.widget.edittext; import com.example.mvpe.r; import com.example.mvpe.presenter.userpersenter; import android.view.view.onclicklistener; import android.widget.toast; /** * created by fendo on 2017/4/29. */ public class useractivity extends activity implements onclicklistener,iuserview{ private edittext userid; private edittext username; private edittext userpwd; private button read; private button write; private userpersenter usp; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); usp=new userpersenter(this); setcontentview(r.layout.activity_main); findviewbyid(); read.setonclicklistener(this); write.setonclicklistener(this); } public void findviewbyid(){ userid= (edittext) findviewbyid(r.id.userid); username= (edittext) findviewbyid(r.id.usertext); userpwd= (edittext) findviewbyid(r.id.userpwd); read= (button) findviewbyid(r.id.read); write= (button) findviewbyid(r.id.write); } @override public int getid() { return integer.parseint(userid.gettext().tostring()); } @override public void setusername(string usernamcc) { username.settext(usernamcc); } @override public void setuserpwd(string userpw) { userpwd.settext(userpw); } @override public string getuserpwd() { return userpwd.gettext().tostring(); } @override public string getusername() { return username.gettext().tostring(); } @override public void onclick(view view) { switch (view.getid()) { case r.id.read : usp.loaduser(getid()); toast.maketext(getapplicationcontext(), "点击了读"+getid(), toast.length_short).show(); break; case r.id.write: usp.saveuser(getid(),getusername(),getuserpwd()); toast.maketext(getapplicationcontext(), "点击了存"+getid()+"--"+getusername()+"--"+getuserpwd(), toast.length_short).show(); break; } } }
可以看到view只负责处理与用户进行交互,并把数据相关的逻辑操作都扔给了presenter去做。而presenter调用model处理完数据之后,再通过iuserview更新view显示的信息。
下载:源码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。