Android MVP 设计模式
来源:互联网 发布:linux修改用户组 编辑:程序博客网 时间:2024/05/29 12:46
这篇文章参照Hongyang的博客整理。
浅谈 MVP in Android
MVP设计模式
何为MVP
1.View 对应于Activity,负责View的绘制以及与用户交互
2.Model 依然是业务逻辑和实体模型
3.Presenter 负责完成View于Model间的交互
Presenter 在这里类似于一个主持人的角色,他负责Model实体类与VIEW表示层的交互,这个交互通常使用接口实现
MVP的特征
Presenter是整个MVP体系的控制中心,而不是单纯的处理View请求的人;
View仅仅是用户交互请求的汇报者,对于响应用户交互相关的逻辑和流程,View不参与决策,真正的决策者是Presenter;
View向Presenter发送用户交互请求应该采用这样的口吻:“我现在将用户交互请求发送给你,你看着办,需要我的时候我会协助你”,不应该是这样:“我现在处理用户交互请求了,我知道该怎么办,但是我需要你的支持,因为实现业务逻辑的Model只信任你”;
对于绑定到View上的数据,不应该是View从Presenter上“拉”回来的,应该是Presenter主动“推”给View的;
View尽可能不维护数据状态,因为其本身仅仅实现单纯的、独立的UI操作;Presenter才是整个体系的协调者,它根据处理用于交互的逻辑给View和Model安排工作。
转变成
MVC设计模式
1. View:对应于布局文件
2. Model:业务逻辑和实体模型
3. Controllor:对应于Activity
MVC与MVP的不同
MVP与MVC最大的不同是Model不能和VIEW直接通信,必须经过Persenter(主持者)
MVP 示例演示
这是模拟登陆的一个demo,使用接口实现MVP设置,在这个demo中,主Activity并没有直接调用Login的业务逻辑(Login的业务逻辑应写在user-Model中),而是使用Persenter通过接口实现login流程,通过接口实现可以进一步解耦。
代码结构
布局文件
<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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.mvp_pattern.MainActivity" > <EditText android:id="@+id/id_et_username" android:layout_width="match_parent" android:layout_height="wrap_content" /> <EditText android:id="@+id/id_et_pwd" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/id_btn_submit" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login" /> <ProgressBar android:id="@+id/id_pb_loading" style="@android:style/Widget.ProgressBar.Inverse" android:layout_width="50dp" android:layout_height="50dp" android:visibility="gone" /></LinearLayout>
下面是Model层
User类
public class User { 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; }}
User模型的登录流程写在BIZ 包中,也属于MODEL
public interface IUserBIZ { void login(String username, String password, OnLoginListener listener);}
public interface OnLoginListener { void loginSuccess(User user); void loginFail();}
登录流程
public class UserBIZ implements IUserBIZ { @Override public void login(final String username, final String password, final OnLoginListener listener) { // 使用子线程模拟耗时操作 new Thread() { @Override public void run() { try { sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 判断是否登录成功 if (username.equals("ytr") && password.equals("123")) { User user = new User(); user.setUsername(username); user.setPassword(password); if (listener != null) { listener.loginSuccess(user); } } else { if (listener != null) { listener.loginFail(); } } }; }.start(); }}
VIEW层,用于描述界面,需用接口进行约束,只后用于和Presenter交互
// 登录界面需实现的接口public interface IUserLoginView { String getUserName(); String getPassword(); void clearUserName(); void clearPassword(); void showLoading(); void hideLoading(); void toMainActivity(); void showFailError();}
Persenter 交互核心,通过接口实现Model和View的交互
// presenter角色,是Model和View交互的桥梁public class LoginPresenter { private IUserBIZ mUserBIZ; private IUserLoginView mLoginView; // 用于在UI线程中更新UI private Handler mHandler = new Handler(); public LoginPresenter(IUserLoginView loginView) { mLoginView = loginView; mUserBIZ = new UserBIZ(); } public void login() { mLoginView.showLoading(); mUserBIZ.login(mLoginView.getUserName(), mLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(User user) { // 在UI线程更新UI mHandler.post(new Runnable() { @Override public void run() { mLoginView.toMainActivity(); // 登录操作 mLoginView.hideLoading(); } }); } @Override public void loginFail() { mHandler.post(new Runnable() { @Override public void run() { mLoginView.showFailError(); // 登录操作 mLoginView.hideLoading(); } }); } }); } public void clear() { mLoginView.clearPassword(); mLoginView.clearUserName(); }}
Activity和LoginPresenter交互 M–V–P交互的实现
public class MainActivity extends ActionBarActivity implements IUserLoginView { private EditText mEtUser; private EditText mEtPwd; private Button mBtnLogin; private ProgressBar mPbLoading; private LoginPresenter mPresenter = new LoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mEtUser = (EditText) findViewById(R.id.id_et_username); mEtPwd = (EditText) findViewById(R.id.id_et_pwd); mBtnLogin = (Button) findViewById(R.id.id_btn_submit); mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading); mBtnLogin.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 登录操作 mPresenter.login(); } }); } @Override public String getUserName() { return mEtUser.getText().toString(); } @Override public String getPassword() { return mEtPwd.getText().toString(); } @Override public void clearUserName() { mEtUser.setText(""); } @Override public void clearPassword() { mEtPwd.setText(""); } @Override public void showLoading() { mPbLoading.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mPbLoading.setVisibility(View.GONE); } @Override public void toMainActivity() { Toast.makeText(this, "toMainActivity()", Toast.LENGTH_SHORT).show(); } @Override public void showFailError() { Toast.makeText(this, "LoginFail", Toast.LENGTH_SHORT).show(); }}
- Android MVP 设计模式
- Android: MVP设计模式
- Android MVP 设计模式
- android MVP设计模式实践
- Android的MVP设计模式
- Android中的MVP设计模式
- Android之mvp设计模式
- 关于Android MVP设计模式
- Android MVP设计模式浅析
- Android之MVP设计模式
- Android,谈谈MVP设计模式
- Android mvp模式设计讨论
- Android设计模式之MVP
- Android之MVP设计模式
- Android设计模式之MVP
- Android 初识mvp设计模式
- Android的设计模式MVP
- Android设计模式之MVP
- flume 用户指南 - part 1
- Python3 函数
- 经典算法题03-猴子吃桃
- mybatis动态sql的书写
- 了解Context
- Android MVP 设计模式
- 动态规划13之1018
- poj 3666 Making the Grade
- exec函数
- EventBus要点解析
- scrapy框架学习二-如何在eclips中配置scrapy开发环境
- Graphical models资料
- Java中HashSet、TreeSet的区别
- Activity强制横/竖屏,全屏和常亮