Android技术分享Android知识Android高级技术

Android MVP初探

2016-08-24  本文已影响1170人  2ece9f02c806

最近Android MVP非常火,特地研究了一翻,至于为什么火,自行百度google
我比较喜欢的两点是:

  1. 业务逻辑与View和Model分离,需求变更的时候修改起来简单
  2. 方便单元测试

未使用MVP程序是这样的


Paste_Image.png

使用MVP后是这样的

Paste_Image.png

那么现在开始用MVP来做一个简单的登录页面:

1. 写接口

- Model层接口

public interface IUserModel {
    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @param callback 回调
     */
    void login(String username, String password, Callback callback);
}

IUserModel接口就一个login方法,参数为用户名,密码以及回调

- Presenter层接口

public interface ILoginPresenter {
    /**
     * 登录
     */
    void login();
}

ILoginPresenter接口就一个login,不需要参数,描述登录这个行为

- View层接口

public interface ILoginView {
    /**
     * 从UI中获取用户输入的用户名
     *
     * @return
     */
    String getUsername();

    /**
     * 从UI中获取用户输入的密码
     *
     * @return
     */
    String getPassword();

    /**
     * 显示加loading
     *
     * @param msg
     */
    void showLoading(String msg);

    /**
     * 取消loading显示
     */
    void hideLoading();

    /**
     * 显示结果
     *
     * @param result
     */
    void showResult(String result);
}

ILoginView方法分两部份:
一部份是给Presenter提供数据的(View->Presenter)
getUsername
getPassword
另一部份是从Presenter接收数据用来显示的(Presenter->View)
showLoading
hideLoading
showResult
说白了就是数据交互

2. 实现接口

- Model层实现

public class UserModel implements IUserModel {

    Handler handler = new Handler();

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @param callback 回调
     */
    @Override
    public void login(final String username, final String password, final Callback callback) {
        handler.postDelayed(new Runnable() {//延时200ms回调,模拟网络请求
            @Override
            public void run() {
                if ("huangx".equals(username) && "123456".equals(password)) {
                    callback.onSuccess();
                } else {
                    callback.onFailure("用户名或密码错误");
                }
            }
        }, 2000);
    }
}

UserModel 是IUserModel 的实现,正常情况就里就是调服务器登录接口,我们Demo这里就用延时操作来模拟网络请求。这里对用户名密码做了一个判断,如果用户名为huangx密码为123456就返回登录成功,否则返回“用户名或密码错误”

- Presenter层实现

public class LoginPresenter implements ILoginPresenter {

    private ILoginView loginView;
    private UserModel userModel;

    public LoginPresenter(ILoginView loginView, UserModel userModel) {
        this.loginView = loginView;
        this.userModel = userModel;
    }

    /**
     * 登录
     */
    @Override
    public void login() {
        loginView.showLoading("登录中...");
        userModel.login(loginView.getUsername(), loginView.getPassword(), new Callback() {
            @Override
            public void onSuccess() {
                loginView.hideLoading();
                loginView.showResult("登录成功");
            }

            @Override
            public void onFailure(String errorMsg) {
                loginView.hideLoading();
                loginView.showResult(errorMsg);
            }
        });
    }
}

LoginPresenter 是ILoginPresenter 的实现,也是MVP中最关键的一个角色,主要的业务逻辑都放在这里,起到连接Model层和View层的作用,从构造方法可以看出,它需要传入ILoginView和IUserModel的实例。
在login方法被调用时,LoginPresenter会从loginView获取到用户输入的用户名和密码,
并以此为参数调用userModel的login方法,
然后通过回调把结果返回给loginView

- View层实现

public class LoginActivity extends AppCompatActivity implements ILoginView, View.OnClickListener {

    private EditText username;
    private EditText password;
    private ProgressDialog progressDialog;
    private LoginPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        username = (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.password);
        findViewById(R.id.login).setOnClickListener(this);
        progressDialog = new ProgressDialog(this);
        presenter = new LoginPresenter(this, new UserModel());
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.login:
                presenter.login();
                break;
        }
    }

    /**
     * 从UI中获取用户输入的用户名
     *
     * @return
     */
    @Override
    public String getUsername() {
        return username.getText().toString().trim();
    }

    /**
     * 从UI中获取用户输入的密码
     *
     * @return
     */
    @Override
    public String getPassword() {
        return password.getText().toString().trim();
    }

    /**
     * 显示加loading
     *
     * @param msg
     */
    @Override
    public void showLoading(String msg) {
        progressDialog.setMessage(msg);
        if (!progressDialog.isShowing()) {
            progressDialog.show();
        }
    }

    /**
     * 取消loading显示
     */
    @Override
    public void hideLoading() {
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    /**
     * 显示结果
     *
     * @param result
     */
    @Override
    public void showResult(String result) {
        Toast.makeText(LoginActivity.this, result, Toast.LENGTH_SHORT).show();
    }
}

LoginActivity 是ILoginView的实现,让LoginPresenter 可以从这里获取到用户名和密码,并用Toast显示登录给果。点击登录按钮的时候调用LoginPresenter 的login方法角色登录动作。

至此就实现了一个最简单的MVP。代码在这里

下一篇:Android MVP进阶

上一篇下一篇

猜你喜欢

热点阅读