美文网首页
MVP之实例篇

MVP之实例篇

作者: 谢尔顿 | 来源:发表于2017-03-27 11:24 被阅读19次

1. 实例1:Google官方的demo思想

业务逻辑:网络请求用户信息接口,并将用户信息展现在UserInfoActivity中。
工程目录结构:


说明:
(1)BaseView.java是所有View的基类
public interface BaseView<T> {
    void setPresenter(T presenter);
}

(2)BasePresenter.java是所有Presenter的基类

public interface BasePresenter {
    void start();
}

这里的start()方法就相当于约定了所有的Presenter的初始化操作都放在start()方法中;

(3)Contract契约接口

public interface UserInfoContract {
    interface View extends BaseView<Presenter> {
        void showLoading();//展示加载框
        void dismissLoading();//取消加载框展示
        void showUserInfo(UserInfoModel userInfoModel);//将网络请求得到的用户信息回调
        String loadUserId();////假设接口请求需要一个userId
    }

    interface Presenter extends BasePresenter {
        void loadUserInfo();//加载用户信息
    }
}

里面放的是契约接口。更能直接明了的看到View和Presenter的方法。

(4)Presenter,UserInfoPresenter实现了契约接口UserInfoContract 里的Presenter接口

public class UserInfoPresenter  implements UserInfoContract.Presenter{
    private UserInfoContract.View mView;

    public UserInfoPresenter(UserInfoContract.View view) {
        mView = view;
        mView.setPresenter(this);
    }


    @Override
    public void loadUserInfo() {
        String userId = mView.loadUserId();
        mView.showLoading();//接口请求前显示loading
        //模拟接口请求回调
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //模拟接口返回的json,并转换为javabean
                UserInfoModel userInfoModel = new UserInfoModel("马云", 50, "杭州");
                mView.showUserInfo(userInfoModel);
                mView.dismissLoading();
            }
        },3000);
    }

    @Override
    public void start() {
        loadUserInfo();
    }

}

(5)View,UserInfoActivity 实现了契约接口UserInfoContract 里的View接口

public class UserInfoActivity extends AppCompatActivity implements UserInfoContract.View {

    private TextView tv_name;
    private TextView tv_age;
    private TextView tv_address;
    private UserInfoContract.Presenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);
        tv_name = ((TextView) findViewById(R.id.tv_name));
        tv_age = ((TextView) findViewById(R.id.tv_age));
        tv_address = ((TextView) findViewById(R.id.tv_address));
        new UserInfoPresenter(this);
        mPresenter.start();
    }

    @Override
    public void setPresenter(UserInfoContract.Presenter presenter) {
        this.mPresenter = presenter;
    }

    @Override
    public void showLoading() {
        Toast.makeText(this, "正在加载。。。", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void dismissLoading() {
        Toast.makeText(this, "加载完成", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showUserInfo(UserInfoModel userInfoModel) {
        if (userInfoModel != null) {
            tv_address.setText(userInfoModel.getAddress());
            tv_age.setText(String.valueOf(userInfoModel.getAge()));
            tv_name.setText(userInfoModel.getName());
        }
    }

    @Override
    public String loadUserId() {
        return "1000";//假设需要查询的用户信息的userId是1000
    }
}

(6)Model就是实体类

2. 实例2:MVP的基本使用--登陆模块

项目的结构图如下:

在项目中使用 MVP 最好通过模块进行分层这样便于管理且结构清晰。

(1)View层代码
接口ILoginView:

public interface ILoginView {
    public void onClearText();
    public void onLoginResult(Boolean result, int code);
}

ILoginView的实现类LoginActivity。

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

    private EditText mName;
    private EditText mPassword;
    private Button mClear;
    private Button mLogin;
    private LoginPresenterCompl loginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        mName = ((EditText) findViewById(R.id.et_name));
        mPassword = ((EditText) findViewById(R.id.et_password));
        mClear = ((Button) findViewById(R.id.btn_clear));
        mLogin = ((Button) findViewById(R.id.btn_login));
        mClear.setOnClickListener(this);
        mLogin.setOnClickListener(this);

        loginPresenter = new LoginPresenterCompl(this);
    }

    @Override
    public void onClearText() {
        mClear.setText("");
        mLogin.setText("");
        Toast.makeText(this, "clear", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLoginResult(Boolean result, int code) {
        mLogin.setEnabled(true);
        mLogin.setEnabled(true);
        if (result){
            Toast.makeText(this, "登陆成功", Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(this, "登陆失败", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onClick(View v) {
        String name = mName.getText().toString();
        String password = mPassword.getText().toString();
        switch (v.getId()){
            case R.id.btn_clear:
                loginPresenter.clear();
                break;
            case R.id.btn_login:
                loginPresenter.doLogin(name,password);
                break;
        }
    }
}

注:在 LoginActivity 中我们可以看到,LoginActivity 实现了 ILoginView 接口,实现了未实现的方法,在代码中可以看出 LoginActivity 并没有做一些逻辑处理工作,数据处理的工作都是调用 ILoginPresenter 完成的。

(2)Presenter层的代码
接口ILoginPresenter:

public interface ILoginPresenter {

    void clear();
    void doLogin(String name,String password);
}

ILoginPresenter的实现类LoginPresenterCompl:

public class LoginPresenterCompl implements ILoginPresenter {

    private  ILoginView loginView;
    private  User user;

    public LoginPresenterCompl(ILoginView view) {
        loginView = view;
        user  = new User("张三","123456");
    }

    @Override
    public void clear() {
        loginView.onClearText();
    }

    @Override
    public void doLogin(String name, String password) {
        boolean result = false;
        int code = 0;
        if (name.equals(user.getName())&& password.equals(user.getPassword())){
            result = true;
            code = 1;
        }else {
            result = false;
            code = 0;
        }
        loginView.onLoginResult(result,code);
    }
}

注:该实现类也比较简单,定义了用户名是张三,密码是123456的一个登陆用户,然后进行登陆和清除的操作。

(3)Model层代码

public class User {
    private String name;
    private String password;

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

相关文章

网友评论

      本文标题:MVP之实例篇

      本文链接:https://www.haomeiwen.com/subject/zowlottx.html