MVP登陆模块
来源:互联网 发布:淘宝客怎么设置 编辑:程序博客网 时间:2024/06/10 22:14
在MVP模式里通常包含4个要素:
(1)View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3)Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4)Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
二、为什么使用MVP模式
在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).
另外,回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。
好了上代码Mvp的登陆模块
首先是View层
定义一个View的interface
public interface Iview { /** * 登录成功 */ void onLoginSuccess(); /** * 登录失败 * * @param error */ void onLoginFailed(String error);}
然后是model层定义接口
public interface Imodel { /** * 登录 * * @param user * @return 约定返回"true"为登录成功,其他为登录失败的错误信息 */ String login(User user);}
创建model层usermodel实现它
public class Usermodel implements Imodel{ @Override public String login(User user) { boolean networkError = false; //网络是否异常 try { Thread.sleep(3000);//模拟网络连接 if (networkError) { return "网络异常"; } else if ("ethanco".equals(user.getUsername()) && "123456".equals(user.getPassword())) { return "true"; } else { return "账号或密码错误"; } } catch (InterruptedException e) { e.printStackTrace(); return e.getMessage(); } }}
接下来是presenter层进行逻辑处理
public class UserPresenter { private final Iview userView; private final Usermodel userMode; public UserPresenter(Iview userView) { this.userView = userView; this.userMode = new Usermodel(); } /** * 登录 * * @param user */ public void login(final User user) { new Thread() { @Override public void run() { final String res = userMode.login(user); new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { if ("true".equals(res)) { userView.onLoginSuccess(); } else { userView.onLoginFailed(res); } } }); } }.start(); }}
在MainActivity里引用
public class MainActivity extends AppCompatActivity implements Iview,View.OnClickListener{ private EditText edituser; private EditText editpass; private ProgressDialog loginProgreess; private UserPresenter userPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edituser = (EditText) findViewById(R.id.editText); editpass = (EditText) findViewById(R.id.editText2); findViewById(R.id.button).setOnClickListener(this); userPresenter = new UserPresenter(this); } @Override public void onClick(View v) { String username = edituser.getText().toString().trim(); String password = editpass.getText().toString().trim(); if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) { Toast.makeText(getApplicationContext(), "账号或密码不能为空", Toast.LENGTH_SHORT).show(); return; } loginProgreess = ProgressDialog.show(this, "登录", "正在登录..."); userPresenter.login(new User(username, password)); } @Override public void onLoginSuccess() { loginProgreess.dismiss(); Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show(); } @Override public void onLoginFailed(String error) { loginProgreess.dismiss(); Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show(); }}
MainActivity的布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.mvpdemo.MainActivity"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="textPersonName"android:ems="10"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:layout_marginTop="150dp"android:hint="请输入用户名"android:textSize="30dp"android:id="@+id/editText" /><Buttonandroid:text="登陆"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/editText2"android:layout_centerHorizontal="true"android:layout_marginTop="141dp"android:textSize="30dp"android:id="@+id/button" /><EditTextandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:inputType="textPassword"android:ems="10"android:layout_marginTop="103dp"android:hint="请输入密码"android:textSize="30dp"android:id="@+id/editText2"android:layout_below="@+id/editText"android:layout_centerHorizontal="true" /> </RelativeLayout>
主要的东西的定义接口,接口回调,还有在presenter里的逻辑处理,开始接触还是有难度的,记住MVP
- View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
- Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
- 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
MVC模式:- View可以与Model直接交互
- Controller是基于行为的,并且可以被多个View共享
- 可以负责决定显示哪个View
阅读全文
0 0
- MVP登陆模块
- MVP登陆
- mvp登陆
- Mvp实现登陆注册
- MVP实现登陆注册
- MVP实现登陆注册
- MVP登陆注册
- mvp模式的登陆
- 登陆模块
- 登陆模块
- MVP模式实现接口登陆
- Android MVP封装模拟登陆
- jsp登陆模块
- php写登陆模块
- Struts2(登陆模块)
- 登陆模块设计
- 登陆模块学习笔记
- Android APP 登陆模块
- poj3345——bribing FIPA
- C++智能指针简单剖析
- JS下视频数据耗时分析
- 51nod 1920 空间统计学
- 使用别名创建自己的命令之---alias
- MVP登陆模块
- ASP.NET MVC多语言处理中请求丢失或参数丢失
- 连续总结第二十二天
- xgboost在Windows下的安装
- NOIP 2007 Senior 4
- 学习笔记5
- ccpc2016杭州D题HDU5936
- 后缀数组2.0--Height数组(bzoj 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式)
- Storm概念、原理详解及其应用(二)Storm Cluster