MVP架构实例讲解-登录界面

MVP优缺点就不介绍了,主要说下应用,今天已程序登录的界面讲解如何用MVP架构,写的不好的地方欢迎指正
在介绍之前,先看下demo的目录结构
这里写图片描述

  • 定义网络相关接口
    网络请求都是共通的,所以可以把网络部分单独摘出来。
    首先定义网络请求状态接口。所有的网络请求都包括开始,成功,不成功。所以网络请求状态接口如下所示
public interface RequestStatus<T> {
    void onStart();

    void onSuccess(T t);

    void onError();

}

使用泛型的原因是返回结果类型不确定。
其次是定义网络请求的方法接口

public interface NetTask<T> {

    /**
     *
     * @param t  请求参数类型不确定
     * @param requestStatus  网络请求状态回调
     */
    void exec(T t,RequestStatus requestStatus);
}

exec()方法里面传入了RequestStatus接口,是为了当网络请求有结果后回调给LoginPreserter用的。

  • 定义LoginActivity 和LoginPresenter需要实现的接口。
    咱们分析下,登录的时候有那些状态。涉及网络请求,为了友好的交互,肯定有显示dialog和隐藏dialog,还有就是登录验证成功和失败。
    1.定义LoginActivity需要实现的接口LoginViewInterface
    2.定义LoginPresenter需要实现的接口LoginPresenterInterface,这个接口用于LoginActivity和LoginPresenter的交互。
public class LoginBaseInterface {

    public interface LoginPresenterInterface<T>{

        void requestToLogin(T t);
    }

    public interface LoginViewInterface<T>{

        void showRequestNetDialog();//展示请求网络的dialog
        void cancelRequestNetDialog();//finish掉dialog

        void LoginSuccess(T t);//登录成功
        void LoginUnSuccess();//登录不成功
    }

}

如代码所示,我将这两个接口写到一个LoginBaseInterface类中了,方便管理。

- Model层处理
因为将的是MVP,所以先说model层吧,在说这个之前先建一个实体类LoginBean,用于存储用户名和密码,因为在网络请求的时候需要用到这两个参数。
model层主要用于请求网络获取数据。所以实现之前定义的网络请求的接口NetTask
请求网络的逻辑都在这里实现。

public class LoginModel implements NetTask<LoginBean> {
    @Override
    public void exec(LoginBean loginBean, RequestStatus requestStatus) {
        String name = loginBean.getUserName();
        String pwd = loginBean.getUserPwd();
        if (name == null && TextUtils.isEmpty(name)) {
            requestStatus.onError();
            return;
        }
        if (pwd == null && TextUtils.isEmpty(pwd)) {
            requestStatus.onError();
            return;
        }

        //这里处理和网络交互的逻辑
        requestStatus.onStart();
        //模拟请求网络

        if (!name.equals("18888888888")) {
            requestStatus.onError();
            return;
        } else {
            if (!pwd.equals("123456")) {
                requestStatus.onError();
                return;
            } else {
                requestStatus.onSuccess("恭喜你登录成功");
            }
        }
    }

}

- View层处理(LoginActivity)
1.实现LoginBaseInterface中的LoginViewInterface并重载里面的方法。
2.得到网络请求的对象,将它和自己传给LoginPresenter以得到LoginPresenter对象。
3.点击登录按钮的时候。调用LoginPresenter里面的方法。
LoginActivity的所有代码

package com.mvptest.mvp_demo.login;

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

import com.mvptest.mvp_demo.R;

public class LoginActivity extends AppCompatActivity implements LoginBaseInterface.LoginViewInterface, View.OnClickListener {

    private ProgressBar mLoginPb;
    /**
     * 手机号
     */
    private EditText mUserMobileEt;
    /**
     * 密码
     */
    private EditText mUserPwdEt;
    /**
     * 登 录
     */
    private TextView mLoginConfirmTv;
    private LoginPresenter loginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
        LoginModel loginModel = new LoginModel();
        loginPresenter = new LoginPresenter(loginModel,this);

    }

    @Override
    public void showRequestNetDialog() {
        if (!mLoginPb.isShown()) {
            mLoginPb.setVisibility(View.VISIBLE); 
        }

    }

    @Override
    public void cancelRequestNetDialog() {
        if (mLoginPb.isShown()) {
            mLoginPb.setVisibility(View.INVISIBLE);
        }
    }

    @Override
    public void LoginSuccess(Object o) {
        if (mLoginPb.isShown()) {
            mLoginPb.setVisibility(View.INVISIBLE);
        }
        Toast.makeText(getApplicationContext(), (String)o, Toast.LENGTH_LONG).show();
    }


    @Override
    public void LoginUnSuccess() {
        if (mLoginPb.isShown()) {
            mLoginPb.setVisibility(View.INVISIBLE);
        }
        Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_LONG).show();
    }

    private void initView() {
        mLoginPb = (ProgressBar) findViewById(R.id.login_pb);
        mUserMobileEt = (EditText) findViewById(R.id.user_mobile_et);
        mUserPwdEt = (EditText) findViewById(R.id.user_pwd_et);
        mLoginConfirmTv = (TextView) findViewById(R.id.login_confirm_tv);
        mLoginConfirmTv.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.login_confirm_tv:
                loginPresenter.requestToLogin(new LoginBean(mUserMobileEt.getText().toString().trim(),mUserPwdEt.getText().toString().trim()));
                break;
        }
    }
}

- Presenter层处理。
1.实现LoginBaseInterface.LoginPresenterInterface接口和网络请求状态接口RequestStatus
2.创建构造方法(参数含有网络请求对象和LoginBaseInterface.LoginViewInterface接口)
3.在请求网络的地方调用网络请求对象中的方法
4.将网络请求结果回调给view

package com.mvptest.mvp_demo.login;

import com.mvptest.mvp_demo.netWork.NetTask;
import com.mvptest.mvp_demo.netWork.RequestStatus;

/**
 * Author:wang_sir
 * Time:2018/5/7 20:48
 * Description:This is LoginPresenter
 * LoginPresenter 实现约定接口中的presenter接口和请求网络状态的接口
 */
public class LoginPresenter implements LoginBaseInterface.LoginPresenterInterface<LoginBean>,RequestStatus<String> {


    private NetTask<LoginBean> netTask;
    private LoginBaseInterface.LoginViewInterface viewInterface;

    public LoginPresenter(NetTask<LoginBean> netTask, LoginBaseInterface.LoginViewInterface viewInterface) {
        this.netTask = netTask;
        this.viewInterface = viewInterface;
    }

    @Override
    public void requestToLogin(LoginBean loginBean) {
        netTask.exec(loginBean,this);
    }

    @Override
    public void onStart() {
        viewInterface.showRequestNetDialog();
    }

    @Override
    public void onSuccess(String str) {
        viewInterface.cancelRequestNetDialog();
        viewInterface.LoginSuccess(str);
    }

    @Override
    public void onError() {
        viewInterface.cancelRequestNetDialog();
        viewInterface.LoginUnSuccess();
    }
}

- 归总下整个流程。

view层。
1.进入到LoginActivity后,先得到网络请求逻辑处理类的对象LoginModel.
2.得到LoginPresenter对象。
3.点击登录按钮的时候。view告诉presenter,你帮我请求下网络(调用LoginPresenter中请求网络的方法。)
presenter层
4.LoginPresenter告诉LoginModel启用请求网络的方法。(在LoginPresenter中请求网络的方法里调用网络请求逻辑处理类LoginModel去请求网络。)
5.LoginModel将请求结果回调给LoginPresenter,LoginPresenter通知view更改。

整个MVP的使用就讲完了,不懂的小伙伴最好自己动手实现一下。不懂的地方可以留言,有问题的地方欢迎指正。

完整代码已提交GitHub。地址:https://github.com/DevelopWb/MVP_DEMO.git

猜你喜欢

转载自blog.csdn.net/csdn_mm/article/details/80232540