Android的MVP模式应用(Login)

在开发Android应用时,一个偶然的机会看到有种MVP模式(Mode-View-Presenter),然后好奇的研究了下这个模式并尝试在现在项目中进行推广。下面就把自己目前学习到知识总结出来。

一、MVP简介

      我理解的MVP是由MVC优化衍生出来的一种模式,MVP将MVC中的Controller层进行了优化而生成了Presenter。Presenter单词翻译为“提出者;任命者;主持人”,Presenter层和MVC的Controller一样,负责核心逻辑,但不一样的是Presenter通过接口协议进行数据传递,并阻断了View和Model的直接联系,从而使View和Model更加专注于自身业务逻辑

二、MVP结构

View

View通常来说就是有Activity、Fragment实现的,View会包含一个或多个Presenter的引用来满足视图的业务逻辑。View和Presenter的交互是双向的,即View层可以调用Presenter的逻辑方法,Presenter也可以控制View的显示。

Presenter

Presenter作为Model和View的桥梁,负责从Model拿到数据进行处理并返回给View。但Presenter和其他两层的沟通是通过接口协议进行的,所以每个Presenter中通常会包涵一个或多个接口协议。

Model

和MVC一样,作为数据仓库只负责对APP数据进行处理。

三、MVP实例(MVPLogin)

       在这里我以登录为例来应用MVP模式,来加深对于MVP模式的认知。

 1、先来看看项目的结构图:

1、View的示例:LoginActivity这个就不说了,ILoginView这个也是一个接口,从LoginActivity中抽离出来的

     方法,LoginActivity实现了ILoginView这个接口。

     ILoginView.java:

package com.tz.mvplogin.login.view;

public interface ILoginView {
	/**
	 * 获取用户名
	 * 
	 * @return
	 */
	public String getUserName();

	/**
	 * 获取密码
	 * 
	 * @return
	 */
	public String getPassWord();

	/**
	 * 显示dialog
	 */
	public void showDialog();

	/**
	 * 隐藏dialog
	 */
	public void hideDialog();
	/**
	 * 显示信息
	 */
	public void showMsg(String msg);
	
	/**
	 * 跳入MainActivity
	 */
	public void pushMainActivity();

}
    MainActivity.java:
package com.tz.mvplogin.login.view;

import com.tz.mvplogin.CustomToast;
import com.tz.mvplogin.MainActivity;
import com.tz.mvplogin.R;
import com.tz.mvplogin.login.persenter.LoginPersenter;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;

public class LoginActivity extends Activity implements OnClickListener,
		ILoginView {

	private EditText mEditTextUserName, mEditTextPassword;
	private Button mButtonLogin;
	private ProgressDialog mProgressDialog;

	private LoginPersenter mPersenter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_login);
		initWeight();
	}

	private void initWeight() {
		mEditTextUserName = (EditText) findViewById(R.id.et_username);
		mEditTextPassword = (EditText) findViewById(R.id.et_password);
		mButtonLogin = (Button) findViewById(R.id.bt_login);
		mButtonLogin.setOnClickListener(this);

		mProgressDialog = new ProgressDialog(LoginActivity.this);
		mProgressDialog.setTitle("提示");
		mProgressDialog.setMessage("正在登录...");
		
		mPersenter = new LoginPersenter(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bt_login:
			mPersenter.login(getUserName(), getPassWord());
			break;
		default:
			break;
		}
	}

	@Override
	public String getUserName() {
		return mEditTextUserName.getText().toString();
	}

	@Override
	public String getPassWord() {
		return mEditTextPassword.getText().toString();
	}

	@Override
	public void showDialog() {
		mProgressDialog.show();
	}

	@Override
	public void hideDialog() {
		mProgressDialog.dismiss();
	}

	@Override
	public void showMsg(String msg) {
		CustomToast.showToast(this, msg, 2000);
	}

	@Override
	public void pushMainActivity() {
		startActivity(new Intent(this, MainActivity.class));
		finish();
	}
}
  大家有木有发现Activity的代码好少 吐舌头,也清晰了好多,没有一点关于逻辑的代码。。。 生气嘎嘎。。那逻辑代码去哪了?别介。。下面就出来了。 得意

2、model的示例:IloginModel是一个接口,里面的方法是从LoginModel中抽象出来的。而LoginModel实现

     了ILoginModel这个接口。

     IloginModel.java:
package com.tz.mvplogin.login.model;

import com.tz.mvplogin.login.ICallBack;

public interface ILoginModel {

	public static final int NETWORK_ERROR = 1;
	public static final int LOGIN_SUCCESS = 2;
	public static final int LOGIN_FALUIRE = 3;
	public static final int LOGIN_ING = 4;
	public static final int CHECK_FALUIRE = 5;

	public void login(String username, String password, ICallBack callBack);
}
    LoginModel.java:
package com.tz.mvplogin.login.model;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVUser;
import com.avos.avoscloud.LogInCallback;
import com.tz.mvplogin.application.App;
import com.tz.mvplogin.login.ICallBack;

public class LoginModel implements ILoginModel {

	private int status = ILoginModel.NETWORK_ERROR;
	private String msg = "";

	@Override
	public void login(String username, String password, final ICallBack callBack) {
		if (validate(username, password)) {
			setStatus(ILoginModel.LOGIN_ING);
			callBack.status(this);
			AVUser.logInInBackground(username, password,
					new LogInCallback<AVUser>() {

						@Override
						public void done(AVUser user, AVException e) {
							if (user != null) {
								// 登录成功
								setStatus(ILoginModel.LOGIN_SUCCESS);
								setMsg("登陆成功");
								App.setUser(user);
								callBack.status(LoginModel.this);
							} else {
								// 登录失败
								e.printStackTrace();
								setStatus(ILoginModel.LOGIN_FALUIRE);
								setMsg("登陆失败");
								callBack.status(LoginModel.this);
							}
						}

					});
		} else {
			callBack.status(this);
		}
	}

	/**
	 * 
	 * @description 验证输入信息
	 * @author houhou
	 * @version 1.0
	 * @createDate 2015年8月3日下午10:54:28
	 * @return
	 */
	private boolean validate(String username, String password) {
		if (username.length() == 0) {
			status = ILoginModel.CHECK_FALUIRE;
			msg = "用户名不能为空";
			return false;
		}
		if (password.length() == 0) {
			status = ILoginModel.CHECK_FALUIRE;
			msg = "密码不能为空";
			return false;
		}
		return true;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

}
      发现了吧。。逻辑代码从Activity中完全抽离出来了 再见。呵呵,得瑟,抽离是抽离出来了,着你怎么和界面进行数据交互呢 疑问?这个就要靠咱们的主持人Presenter了 惊讶,接下来有请主持人闪亮登场 骂人 骂人。。。。

3、Presenter示例:这个分别类持有IloginModel和ILoginView这两个对象,一个是数据逻辑,一个是界面交互。

     哈哈,看到这明白了吧,我左手(ILoginModel)右手(ILoginView)一起慢动作吐舌头,逻辑和界面就交互了。

    Presenter.java:

package com.tz.mvplogin.login.persenter;

import com.tz.mvplogin.login.ICallBack;
import com.tz.mvplogin.login.model.ILoginModel;
import com.tz.mvplogin.login.model.LoginModel;
import com.tz.mvplogin.login.view.ILoginView;

public class LoginPresenter {

	private ILoginView mLoginView;// 视图层
	private ILoginModel mLoginModel;// 逻辑层

	public LoginPresenter(ILoginView view) {
		mLoginView = view;
		mLoginModel = new LoginModel();
	}

	public void login(String username, String password) {
		mLoginModel.login(username, password, new ICallBack() {

			@Override
			public void status(LoginModel model) {
				switch (model.getStatus()) {
				case ILoginModel.LOGIN_ING:
					mLoginView.showDialog();
					break;
				case ILoginModel.CHECK_FALUIRE:
					mLoginView.showMsg(model.getMsg());
					break;
				case ILoginModel.LOGIN_FALUIRE:
					mLoginView.hideDialog();
					mLoginView.showMsg(model.getMsg());
					break;
				case ILoginModel.LOGIN_SUCCESS:
					mLoginView.hideDialog();
					mLoginView.pushMainActivity();
					break;
				}
			}
		});
	}
}
4、到这里,MVP模式算是说完了,还有一个ICallBack是一个登录完成后回调的一个接口类:

      ICallBack.java:

package com.tz.mvplogin.login;

import com.tz.mvplogin.login.model.LoginModel;

public interface ICallBack {
	public void status(LoginModel model);
}
哦,差点忘了说了,登录用户名和密码都是:mvplogin(这个是用的LeanCloud,不知道的可以问问度娘)。
下面是运行截图:

  


这里我放上这个Demo的下载地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值