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里面的操作。方便了日后功能性的修改调整。
这里如有讲解不充足的地方,大家谅解下