android开发mvp,Android开发模式之MVP
一、 什么是MVP
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
二、MVP与MVC的区别
作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。
MVC模式
MVP模式
三、Android中的MVP
代码案例:Login MVP
Model
/** 模型层 ——— 登录接口 **/
public interface ILoginModel {
void login(String username, String password, LoginCallBack callBack);
}
/** 模型层 ——— 完成具体的数据操作。 **/
public class LoginModel implements ILoginModel {
@Override
public void login(String username, String password, LoginCallBack callBack) {
if (username.equals("MVP") && password.equals("MVP")){
callBack.onLoginSuccess();
}else{
callBack.onLoginFail();
}
}
}
View
/** 视图层 ——— 视图操作接口 **/
public interface ILoginView {
void initView();
void onUsernameEmpty(); // 用户名为空时的显示操作
void onPasswordEmpty(); // 密码为空时的显示操作
void onLoginSuccess(); // 登陆成功时的显示操作
void onLoginFail(); // 密码失败时的显示操作
}
/** 视图层 ——— 只是作为接受用户数据和展示数据的方式 **/
public class LoginView extends LinearLayout implements ILoginView, View.OnClickListener{
private Context context;
private EditText mUsername;
private EditText mPassword;
private Button mLoginBtn;
private ILoginPresenter presenter;
public LoginView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
public void initView(){
mUsername = (EditText) findViewById(R.id.et_username);
mPassword = (EditText) findViewById(R.id.et_password);
mLoginBtn = (Button) findViewById(R.id.btn_login);
presenter = new LoginPresenter(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_login:
presenter.login(mUsername.getText().toString(),
mPassword.getText().toString());
break;
}
}
@Override
public void onUsernameEmpty() {
Toast.makeText(context, "用户名不能为空", Toast.LENGTH_SHORT).show();
}
@Override
public void onPasswordEmpty() {
Toast.makeText(context, "密码不能为空", Toast.LENGTH_SHORT).show();
}
@Override
public void onLoginSuccess() {
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onLoginFail() {
Toast.makeText(context, "登录失败", Toast.LENGTH_SHORT).show();
}
}
Presenter
public interface ILoginPresenter {
void login(String username, String password);
}
public class LoginPresenter implements ILoginPresenter, LoginCallBack{
private ILoginModel loginModel;
private ILoginView loginView;
public LoginPresenter(ILoginView loginView){
loginModel = new LoginModel();
this.loginView = loginView;
}
@Override
public void login(String username, String password) {
if (TextUtils.isEmpty(username)){
loginView.onUsernameEmpty();
}else if (TextUtils.isEmpty(password)){
loginView.onPasswordEmpty();
}else {
loginModel.login(username, password, this);
}
}
@Override
public void onLoginSuccess() {
loginView.onLoginSuccess();
}
@Override
public void onLoginFail() {
loginView.onLoginFail();
}
}
else
/** 此时Activity就变为了承载视图层的容器。 **/
public class MainActivity extends AppCompatActivity {
private LoginView loginview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPresenter();
}
private void initPresenter(){
loginview = (LoginView) findViewById(R.id.loginview);
loginview.initView();
}
}
xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:orientation="vertical"
android:id="@+id/loginview">
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"/>
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:inputType="textPassword"/>
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Login"
android:layout_marginTop="10dp"/>
三、 MVP模式的优缺点
优点:
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
缺点:
由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。比如说,原本用来呈现Html的Presenter现在也需要用于呈现Pdf了,那么视图很有可能也需要变更。
android开发mvp,Android开发模式之MVP相关推荐
- mvvm模式和mvc的区别_Android 开发中的架构模式 -- MVC / MVP / MVVM
预备知识 了解 Android 基本开发 看完本文可以达到什么程度 了解如何分析一个架构模式 掌握 MVC,MVP,MVVM 架构定义和实现 更多面试内容,面试专题,flutter视频 全套,音视频从 ...
- android filehelper,为AndroidStudio开发mvp插件(MvpHelper)
如果觉得写mvp有点枯燥无味,我们可以做点 cool 的事情:做个 as 插件 help.png todo-mvp: 基础的MVP架构. todo-mvp-loaders:基于MVP架构的实现,在获取 ...
- 浅谈开发中的MVVM模式及与MVP和MVC的区别
2019独角兽企业重金招聘Python工程师标准>>> 我记得前段时间分享了一篇文章< 浅谈Andorid开发中的MVP模式>(点击可跳转),反响不错,为了进一步介绍MV ...
- 【Android 应用开发】Android 返回堆栈管理 ( 默认启动模式 | 栈顶复用启动模式 | 栈内复用启动模式 | 单实例启动模式 | CLEAR_TOP 标识 )
文章目录 I . 默认启动模式 ( standard ) II . 栈顶复用启动模式 ( singleTop ) III . 栈内复用启动模式 ( singleTask ) IV . 单实例启动模式 ...
- Android初级开发笔记-- activity启动模式的学习(1)
第一次学习Android中一个很重要的概念,启动模式.文章记录的也只是一些入门知识,随着学习的深入还会有activity启动模式的学习(2)和(3). 下面分三个小点说一下对启动模式的理解区别以及如何 ...
- Android USB开发小结:host模式与accessory模式
很早之前就想对Android USB的两种模式作个小结,但是一直没有空去搞,毕竟USB这块应该属于冷门方向,并且应用层能够做的比较少也很简单.最近刚好在做大疆无人机的二次开发,想着对USB连接检测这块 ...
- android rom 工作,Android ROM开发(4) bootloader 三种启动模式
Andrew Huang 转载请注明作者及网址 HTC手机中用的bootloader称为HBoot,不知道是不是HTC Bootloader 之意,从官网的源码看这个bootloader不象是u-bo ...
- android项目小说阅读开发背景颜色,Android 小说阅读护眼模式
Android 小说阅读护眼模式 实现方案:采用全局dialog 覆盖APP 悬浮在 其他APP之上,给dialog设置护眼色值 自定义护眼模式dialog public class EyeProt ...
- Android App的设计架构:MVC,MVP,MVVM与架构经验谈
本文转载自https://www.tianmaying.com/tutorial/AndroidMVC,原文作者周鸿博. 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开 ...
最新文章
- 交换机IEEE 802.1Q、VLAN ID、QoS之间的关系
- 微软企业库4.1学习笔记(三)企业库迁移和并行使用,以及企业库的扩展
- H3C LMI协议标准
- 在.net中读写XML方法的总结[转]
- yolov3安卓实现_从零实现YOLOv3
- C++11六大函数(构造函数,移动构造函数,移动赋值操作符,复制构造函数,赋值操作符,析构函数)
- python列表的特点_python基础(一)列表、集合和元组的基本特性
- 加快 DHTML 的一组技巧
- 使用MVC2模式创建新闻网站
- ip首部可选字段_IP报文格式及各字段意义
- 朴素贝叶斯分类器常用的三种条件概率模型:伯努利、多项式、高斯模型
- QQ防撤回9.0.2 软件 源码 源文件
- Fiddler自动回复器伪造回复
- 2015级计算机科学与技术2班班级博客大全
- 【FICO】标准成本、计划成本、实际成本、目标成本
- iphone4s在ios7下解决卡顿问题
- 【新知实验室】关于实时音视频
- java判断时间段是否交叉重叠
- Our replica set configuration is invalid or does not include us
- Java后端社招面试个人总结