MVP介绍
MVP结构图
MVP各层
- M层: 实体模型和业务逻辑
- V层: 对应于Activity,负责View的绘制以及与用户交互
- P层:负责完成View于Model间的交互,减少了Activity的职责,简化了Activity中的代码,将复杂的逻辑代码提取到了Presenter中进行处理。
用户登录示例
效果图
项目目录如图
View层
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名" />
<EditText
android:id="@+id/et_passwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:password="true" />
<Button
android:id="@+id/bt_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录" />
</LinearLayout>
需要定义一个接口view让Presenter操作View。此接口需要的功能有:登录成功跳转到主界面,登录失败给用户提醒,显示加载对话框,取消加载对话框,获取用户输入的用户名和密码。此接口为:ILoginView
package com.sjb.mvpdemo.view;
import com.sjb.mvpdemo.model.entity.UserEntity;
public interface ILoginView {
void toMainActivity(UserEntity user);
void loginFailed();
void showLoadingDialog();
void dismissLoadingDialog();
String getUserName();
String getPasswd();
}
登录Activity需要实现此接口,然后通过Presenter调用接口中的方法,与View交互。
package com.sjb.mvpdemo.view.activity;
import com.sjb.mvpdemo.R;
import com.sjb.mvpdemo.R.id;
import com.sjb.mvpdemo.R.layout;
import com.sjb.mvpdemo.R.menu;
import com.sjb.mvpdemo.model.entity.UserEntity;
import com.sjb.mvpdemo.presenter.LoginPresenter;
import com.sjb.mvpdemo.view.ILoginView;
import android.support.v7.app.ActionBarActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends ActionBarActivity implements ILoginView,
OnClickListener {
private EditText et_username, et_passwd;
private Button bt_login;
private ProgressDialog progressDialog;
private LoginPresenter mLoginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initDatas();
initEvents();
}
private void initEvents() {
bt_login.setOnClickListener(this);
}
private void initDatas() {
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录中。。。");
mLoginPresenter=new LoginPresenter(this);
}
private void initViews() {
et_username = (EditText) findViewById(R.id.et_name);
et_passwd = (EditText) findViewById(R.id.et_passwd);
bt_login = (Button) findViewById(R.id.bt_login);
}
@Override
public void toMainActivity(UserEntity user) {
Toast.makeText(this, "登录成功,跳转界面", Toast.LENGTH_SHORT).show();
}
@Override
public void loginFailed() {
Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
}
@Override
public void showLoadingDialog() {
progressDialog.show();
}
@Override
public void dismissLoadingDialog() {
progressDialog.dismiss();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_login:
mLoginPresenter.login();
break;
}
}
@Override
public String getUserName() {
return et_username.getText().toString().trim();
}
@Override
public String getPasswd() {
return et_passwd.getText().toString().trim();
}
}
Presenter层
通过获取View层LoginActivity传来的ILoginModel来操作View,获取model对象调用业务逻辑。
package com.sjb.mvpdemo.presenter;
import android.os.Handler;
import com.sjb.mvpdemo.listener.IOnLoginListener;
import com.sjb.mvpdemo.model.ILoginModel;
import com.sjb.mvpdemo.model.LoginModelImpl;
import com.sjb.mvpdemo.model.entity.UserEntity;
import com.sjb.mvpdemo.view.ILoginView;
public class LoginPresenter {
private ILoginView mLoginView;// 操作登录页面
private ILoginModel mLoginModel;
private Handler myHandler = new Handler();
public LoginPresenter(ILoginView loginView) {
this.mLoginView = loginView;
mLoginModel = new LoginModelImpl();
}
public void login() {
UserEntity user=new UserEntity(mLoginView.getUserName(), mLoginView.getPasswd());
mLoginView.showLoadingDialog();
mLoginModel.login(user, new IOnLoginListener() {
@Override
public void onSuccess(final UserEntity user) {
// TODO Auto-generated method stub
myHandler.post(new Runnable() {
@Override
public void run() {
mLoginView.dismissLoadingDialog();
mLoginView.toMainActivity(user);
}
});
}
@Override
public void onFailed() {
myHandler.post(new Runnable() {
@Override
public void run() {
mLoginView.dismissLoadingDialog();
mLoginView.loginFailed();
}
});
}
});
}
}
model层
实体类UserEntity
package com.sjb.mvpdemo.model.entity;
import java.io.Serializable;
//MVP中的实体类(属于Model)
public class UserEntity implements Serializable{
private String userName;
private String passwd;
public UserEntity(String userName, String passwd) {
super();
this.userName = userName;
this.passwd = passwd;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
定义一个Model接口ILoginModel添加一个login方法
package com.sjb.mvpdemo.model;
import com.sjb.mvpdemo.listener.IOnLoginListener;
import com.sjb.mvpdemo.model.entity.UserEntity;
public interface ILoginModel {
void login(UserEntity user,IOnLoginListener listener);
}
此model接口的实现类LoginModelImpl
package com.sjb.mvpdemo.model;
import com.sjb.mvpdemo.listener.IOnLoginListener;
import com.sjb.mvpdemo.model.entity.UserEntity;
public class LoginModelImpl implements ILoginModel {
@Override
public void login(final UserEntity user, final IOnLoginListener listener) {
new Thread() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//本地模拟用户名密码是否正确
if (user.getUserName().equals("user")
&& user.getPasswd().equals("123")) {
listener.onSuccess(user);
} else {
listener.onFailed();
}
};
}.start();
}
}