您的位置:首页 > 其它

通过用户登陆例子来学习MVP模式

2016-10-21 09:43 323 查看
MVC模式相信大家不陌生,那么MVP又是个什么模式呢?看下面:

View 对应于Activity,负责View的绘制以及与用户交互
Model 依然是业务逻辑和实体模型
Presenter 负责完成View于Model间的交互



我们通过代码示例来了解MVP。demo效果图这里就不贴了,很简单就是一个登陆例子。

这是项目结构图:



首先新建一个存放实体类的包,简历实体模型Userbean.java

package com.example.as_mvp_test.bean;

/**
* Created by W61 on 2016/10/19.
*/
public class UserBean
{
private String username ;
private String password ;

public String getUsername()
{
return username;
}

public void setUsername(String username)
{
this.username = username;
}

public String getPassword()
{
return password;
}

public void setPassword(String password)
{
this.password = password;
}
}


既然是登陆,那么这里还需要一个登陆的接口,里面需要用户名,密码2个参数。当然还需要一个登陆成功或失败的一个监听接口。共3个参数。如下:

package com.example.as_mvp_test.impl;

import com.example.as_mvp_test.impl.listener.OnLoginListener;

/**
* Created by W61 on 2016/10/19.
*/
public interface  IUserBeanImpl {

/**
* 登陆方法
* @param username  用户名
* @param password  密码
* @param loginListener  login接口
*/
public void login(String username, String password, OnLoginListener loginListener);
}


这里我们把OnLoginListener单独提取出来写一个监听接口,如下:

package com.example.as_mvp_test.impl.listener;

import com.example.as_mvp_test.bean.UserBean;

/**
* Created by W61 on 2016/10/19.
*/
public interface OnLoginListener {

/**
* 登陆成功
* @param userBean
*/
void loginSuccess(UserBean userBean);

/**
* 登录失败
*/
void loginFailed();
}


这里在登陆成功里面有一个Userbean实体。因为通常在登陆成功后我们会拿到用户信息保存下来,以便后续的调用。所以这里在登陆成功后将userbean传出来。

现在有了登陆接口,登陆之后的监听。现在就要写请求服务器这块的逻辑了。这里我们就可以看出来MVP的层次结构非常清晰了,它将这请求的逻辑单独提取。如下:

package com.example.as_mvp_test.impl.biz;

import com.example.as_mvp_test.bean.UserBean;
import com.example.as_mvp_test.impl.IUserBeanImpl;
import com.example.as_mvp_test.impl.listener.OnLoginListener;

/**
* 将请求服务器的逻辑提取到这里来
* Created by W61 on 2016/10/19.
*/
public class UserLoginBiz implements IUserBeanImpl{
@Override
public void login(final String username, final String password, final OnLoginListener loginListener) {
//模拟子线程耗时操作
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(3000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//模拟登录成功
if ("henry".equals(username) && "123456".equals(password))
{
UserBean userBean = new UserBean();
userBean.setUsername(username);
userBean.setPassword(password);
loginListener.loginSuccess(userBean);
} else
{
loginListener.loginFailed();
}
}
}.start();
}

}


上面可以看到。userloginbzi实现iuserbeanimpl登陆接口,并重写了里面的login方法。

到这里差不多完成了一般了。现在我们暴露接口给activity,以便在activity中将用户名,密码等参数传过来。这个借口我们就需要获取用户名,获取密码,登陆请求时的加载框显示与隐藏,失败或成功后通知activity做相应操作的一系列方法,这里的为什么又要写一遍失败或成功方法。在上面代码中将success()或failed()是要传给MVP中的presenter

这个presenter在来做view与modle之间的事情。代码如下:

package com.example.as_mvp_test.view;

import com.example.as_mvp_test.bean.UserBean;

/**
* Created by W61 on 2016/10/19.
*/
public interface IUserLoginView {
/**
* 获取用户名
* @return
*/
String getUserName();

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

/**
*  清空用户名
*/
void clearUserName();

/**
* 清空密码
*/
void clearPassword();

/**
* 显示加载框
*/
void showLoading();

/**
* 隐藏加载框
*/
void hideLoading();

/**
* 成功后通知activity
* @param userBean
*/
void toMainActivity(UserBean userBean);

/**
*  失败的处理
*/
void showFailedError();

}


package com.example.as_mvp_test.presenter;

import android.os.Handler;

import com.example.as_mvp_test.bean.UserBean;
import com.example.as_mvp_test.impl.IUserBeanImpl;
import com.example.as_mvp_test.impl.biz.UserLoginBiz;
import com.example.as_mvp_test.impl.listener.OnLoginListener;
import com.example.as_mvp_test.view.IUserLoginView;

/**
* Created by W61 on 2016/10/19.
*/
public class UserLoginPresenter {

private UserLoginBiz userLoginBiz;
private IUserLoginView userLoginView;
private Handler mHandler = new Handler();

public UserLoginPresenter(IUserLoginView userLoginView)
{
this.userLoginView = userLoginView;
this.userLoginBiz = new UserLoginBiz();
}

public void login()
{
userLoginView.showLoading();
userLoginBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener()
{
@Override
public void loginSuccess(final UserBean user)
{
//需要在UI线程执行
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
});

}

@Override
public void loginFailed()
{
//需要在UI线程执行
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.showFailedError();
userLoginView.hideLoading();
}
});

}
});
}

public void clear()
{
userLoginView.clearUserName();
userLoginView.clearPassword();
}

}


最后在activity中实现Iuserloginview。重写里面的一系列方法即可,代码如下:

package com.example.as_mvp_test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.as_mvp_test.bean.UserBean;
import com.example.as_mvp_test.presenter.UserLoginPresenter;
import com.example.as_mvp_test.view.IUserLoginView;

public class MainActivity extends AppCompatActivity implements IUserLoginView {

private EditText username_ed, userpwd_ed;
private Button login_btn;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}

private void initView() {
username_ed = (EditText) findViewById(R.id.username_ed);
userpwd_ed = (EditText) findViewById(R.id.userpwd_ed);
findViewById(R.id.login_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO 登陆
mUserLoginPresenter.login();
}
});
}

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

@Override
public String getPassword() {
return userpwd_ed.getText().toString().trim();
}

@Override
public void clearUserName() {

}

@Override
public void clearPassword() {

}

@Override
public void showLoading() {
//        mPbLoading.setVisibility(View.VISIBLE);
}

@Override
public void hideLoading() {
//        mPbLoading.setVisibility(View.GONE);
}

@Override
public void toMainActivity(UserBean userBean) {
Toast.makeText(this, userBean.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}

@Override
public void showFailedError() {
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}

}


一个MVP模式的登陆例子完成了。大家可以看出来MVP通俗点讲就是分包了很多,全都是通过接口调用。减少了activity里面的操作。方便了日后功能性的修改调整。

这里如有讲解不充足的地方,大家谅解下




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: