android mvp文件目录 安卓手机如何打开.mvp文件
转载
Android中MVP的使用
以前在写项目的时候,没有过多考虑架构模式的问题,所以一开始使用的都是类似MVC的架构,严格来讲,之前的项目都不算MVC模式,只是简单的将网络请求与界面分离,然后通过Handler通知更新界面。随着项目越来越大,Activity和Fragment中代码越来越多,导致项目的维护变得越来越复杂,一开始重构成了MVC模式,随着深入了解,发现MVP模式能够大大减少Model和View层之间的耦合度,遂又将项目重构成MVP模式。最近又发现MVP已经开始不能满足需求,正在研究MVVM,后期会将MVVM的研究成果奉上。
当然不是所有的模块都使用MVP,MVP适合在一些逻辑复杂的模块中使用,如果业务逻辑简单,一个Activity就能搞定,也没有必要生搬硬套的做成MVP模式的。只要整体的模式思路使用MVP模式,其中夹杂一些MVC模式,甚至简单的模块不使用模块,不会对整个项目有太大的影响,反而是最优选择。
MVP模式也有其缺点,首先就是代码量多了,文件数量大大提升,但换来的好处是项目结构清晰,在前期只有原型图的时候,我们也可以提前开发,Model层负责数据的请求和数据的处理,写好Presenter层和View层后,基本不用改,只需关注Model层的变化就可以了;还是就是Activity内部类基本不再使用了,部分UI逻辑判断也可以转到Presenter去处理,View层(UI)也非常清晰干净。
什么是MVP
MVP是 模型(Model)、视图(View)、主持人(Presenter)的缩写,代表不同模块。
模型(Model):负责处理数据的加载或者存储;比如从网络或者本地数据库获取数据。
视图(View):负责界面数据的展示,与用户进行交互。
主持人(Presenter):相当于协调者,是Model和View层之间的桥梁,占据主导地位。
如图所示,Model层和View并不直接交互,而是通过Presenter层进行交互。Presenter持有Model层和View层的Interface的引用,而View层持有Presenter层Interface的引用。当View层需要展示数据的时候,会调用Presenter层的某个接口,然后Presenter层会调用Model层请求数据,当Model层数据获取成功后会调用Presenter层的回调方法通知Presenter层数据加载完毕,然后Presenter层再调用View层的接口将获取到的数据展示给用户。
整个过程,View层告知Presenter层需要什么数据,Presenter层调用Model获取数据,Model数据获取完成告知Presenter层,Presenter层再调用View层将数据展示给用户。
这样分层减少了Model层和View层的耦合度:
1、可以使得Model层和View层单独开发与测试,互补依赖;
2、可以将Model层封装复用,减少代码量
3、方便构建单元测试,测试逻辑中存在的潜在BUG
4、清晰的结构,便于维护
准备工作
创建LoginBean类
public class LoginBean {
private String mName;
private String mPassWord;
public String getmName(){
return mName;
}
public void setmName(String name){
mName = name;
}
public String getmPassWord(){
return mPassWord;
}
public void setmPassWord(String passWord){
mPassWord = passWord;
}
}
|
模型层(Model)
1. 先写一个接口
public interface ILoginModel {
void login(String username, String password, OnLoginListener loginListener);
interface OnLoginListener{
void LoginSuccess(LoginBean loginBean);
void LoginFail();
}
}
|
2. 继承接口进行数据请求
public class LoginModel implements ILoginModel {
@Override
public void login(String username, String password, OnLoginListener loginListener) {
//模拟子线程耗时操作
simulationRequest(username, password, loginListener);
}
private void simulationRequest(final String username, final String password,final OnLoginListener loginListener) {
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(username.equals("Lking") && password.equals("123456")){//登录成功
LoginBean loginBean = new LoginBean();
loginBean.setmName(username);
loginBean.setmPassWord(password);
loginListener.LoginSuccess(loginBean);
}else{//登录失败
loginListener.LoginFail();
}
}
}.start();
}
}
|
视图层(View)
1、先写一个接口
public interface ILoginView {
/** 获取账号*/
String getName();
/** 获取密码*/
String getPassword();
/** 显示加载圈*/
void showLoading();
/** 关闭加载圈*/
void hideLoading();
/** 跳转到主界面*/
void toMainActivity(LoginBean loginBean);
/** 显示失败提示*/
void showFailToast();
}
|
2、编写布局文件activity_mvp.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_ffffff"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="账 号:"
android:textColor="@color/color_000000"
android:textSize="18sp" />
<EditText
android:id="@+id/lking_mvp_name_edt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="请输入账号"
android:textColor="@color/color_000000"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="密 码:"
android:textColor="@color/color_000000"
android:textSize="18sp" />
<EditText
android:id="@+id/lking_mvp_pas_edt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="请输入密码"
android:textColor="@color/color_000000"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="@+id/lking_mvp_login_txt"
android:layout_width="match_parent"
android:layout_height="45dp"
android:gravity="center"
android:text="登录"
android:textColor="@color/color_000000"
android:textSize="18sp" />
<ProgressBar
android:id="@+id/lking_mvp_login_pro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:layout_marginTop="20dp" />
</LinearLayout>
|
3、继承接口进行数据显示
public class MvpActivity extends Activity implements ILoginView {
private EditText mNameEdt;
private EditText mPasswordEdt;
private TextView mLoginBtn;
private ProgressBar mLoading;
private LoginPresenter mLoginPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
initViews();
}/**
* 初始化控件
*/
private void initViews() {
mNameEdt = (EditText) findViewById(R.id.lking_mvp_name_edt);
mPasswordEdt = (EditText) findViewById(R.id.lking_mvp_pas_edt);
mLoginBtn = (TextView) findViewById(R.id.lking_mvp_login_txt);
mLoading = (ProgressBar) findViewById(R.id.lking_mvp_login_pro);
mLoginPresenter = new LoginPresenter(this);
mLoginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLoginPresenter.login();
}
});
}
@Override
public String getName() {
return mNameEdt.getText().toString().trim();
}
@Override
public String getPassword() {
return mPasswordEdt.getText().toString().trim();
}
@Override
public void showLoading() {
mLoading.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
mLoading.setVisibility(View.GONE);
}
@Override
public void toMainActivity(LoginBean loginBean) {
Toast.makeText(this, "登录成功,跳转到主界面", Toast.LENGTH_SHORT).show();
}
@Override
public void showFailToast() {
Toast.makeText(this, "登录失败,请重新输入账号和密码", Toast.LENGTH_SHORT).show();
mNameEdt.setText("");
mPasswordEdt.setText("");
}
}
|
主持人(Presenter)
创建管理逻辑类 public class LoginPresenter {
private ILoginView mILoginView;
private LoginModel mLoginModel;
private Handler mHandler = new Handler();
public LoginPresenter(ILoginView iLoginView) {
mILoginView = iLoginView;
mLoginModel = new LoginModel();
}
public void login(){
mILoginView.showLoading();
mLoginModel.login(mILoginView.getName(), mILoginView.getPassword(), new ILoginModel.OnLoginListener() {
@Override
public void LoginSuccess(final LoginBean loginBean) {
mHandler.post(new Runnable() {
@Override
public void run() {
mILoginView.hideLoading();
mILoginView.toMainActivity(loginBean);
}
});
}
@Override
public void LoginFail() {
mHandler.post(new Runnable() {
@Override
public void run() {
mILoginView.hideLoading();
mILoginView.showFailToast();
}
});
}
});
}
}
|
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。