MVP简单实现

来源:互联网 发布:服装图设计软件 编辑:程序博客网 时间:2024/06/05 20:45

我这里不多说什么是MVP,重点说怎么写MVP;

说明: MVP和MVC的最大区别:MVP中M和V之间没有直接的联系;V和P之间也是通过接口联系的。

先看看他的目录结构:在这里可以看见model、presenter、view三个包。
这里写图片描述

然后看看里面的详细目录:

这里写图片描述

好了下面开始创建我们的类了:

  • 1、首先看看view层

我们模仿登录,界面很简单,有两个EditText和一个button。

这里写图片描述

view层有两个东西,一个是Activity,一个是View的接口;Activity还是之前的Activity但是里面的所有业务逻辑都是抽成方法,放到了View的接口中。

分析一下有哪些业务逻辑呢?就是有哪些功能:

1)获取EditText上的文字,及获取用户名和密码;
2)点击Button的时候弹出加载动画,登录成功后取消加载动画;
3)点击button时改变button的状态,如改变文字等;

所以我们View层的接口就搞定了

/** * Created by ws on 17/8/4. * View层的接口,主要是界面的显示,和用户的良好交互 * * 分析:1、点击button的时候要显示Progress,加载之后隐藏progress *      2、点击button后改变button的文字状态,颜色等,这里只实现了文字,其他的根据需求定义哈 *      3、可以获取用户名和密码 * * 对应的Activity要实现这个接口,因为所有的View都在Activity上进行的初始化 */public interface LoginViewInterface {    void showProgress();    void hindProgress();    void changeButtonText(String btn_text);    String getUsername();    String getPassword();}

然后说说我们的Activity,Activity一定要实现View的接口,要不啥也干不了,Activity中的动作都写在了接口中,但是具体的实现还是在Activity中实现的,还有Activity的另一个作用就是初始化,初始化那些View。

view要与presenter又关系,但是又不能直接实现presenter的接口,这样还会造成在view中操作model,所以只能持有presenter的接口的实现类的引用,从而可以保证在presenter中既操作了view又操作了model

public class LoginActivity extends AppCompatActivity implements LoginViewInterface {    private EditText mUserNameEdit;    private EditText mPasswordEdit;    private Button mLoginBtn;    private LinearLayout mLoadingLinear;    private ContentLoadingProgressBar mLoadingPregress;    private LoginMVPim loginMVPim;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_login);        initViews();        initListeners();    }    private void initViews() {        mUserNameEdit = (EditText) findViewById(R.id.a_login_edit_username);        mPasswordEdit = (EditText) findViewById(R.id.a_login_edit_password);        mLoginBtn = (Button) findViewById(R.id.a_login_btn_login);        mLoadingLinear = (LinearLayout) findViewById(R.id.a_login_linear_progress);        mLoadingPregress = (ContentLoadingProgressBar) findViewById(R.id.a_login_pg_progress);        //持有presenter的引用(通过presenter来操作model)        loginMVPim = new LoginMVPim(this);    }    private void initListeners() {        mLoginBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                loginMVPim.loginMV();            }        });    }    @Override    public void showProgress() {        mLoadingLinear.setVisibility(View.VISIBLE);        mLoadingPregress.show();    }    @Override    public void hindProgress() {        mLoadingLinear.setVisibility(View.GONE);        mLoadingPregress.hide();    }    @Override    public void changeButtonText(String btn_text) {        mLoginBtn.setText(btn_text);    }    @Override    public String getUsername() {        return mUserNameEdit.getText().toString();    }    @Override    public String getPassword() {        return mPasswordEdit.getText().toString();    }}
  • 2、接下来看看model层

先说个最简单的实体类,和正常的没区别

public class User {    private String username;    private String password;    public User(String username, String password) {        this.username = username;        this.password = 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;    }}

view层是处理界面的,model是处理数据的,view层的接口实现了一些可以改变界面的东西,那model层的接口就是改变数据了,我们的例子中什么时候会操作数据呢,只有在登录的时候,会涉及到数据,所以model层的接口中的方法就确定了。

public interface UserModelInterface {    //登录的时候我们要知道用户名和密码,同时还要知道登录的结果,所以就给了个接口用来回调。    void login(String username, String password, LoginCallBack callBack);}

注意:
这个回调在presenter层,因为它给Model层回调,更改View层的状态,确保 Model层不直接操作View层。

疑问

这里可能会有疑问,为什么model层的接口和presenter层的接口都有实现的类,而view层的直接由Activity实现了呢?
因为view层的接口都是操作View的,这些View又都是在Activity中初始化的,自然而然就由Activity实现了。

public class UserModelInterfaceIm implements UserModelInterface {    @Override    public void login(String username, String password, LoginCallBack callBack) {        //只是模拟,具体的自己修改        if ("15811470222".equals(username) && "123456".equals(password)){            callBack.loginSuccess("成功啦");            User user  = new User(username,password);        }else {            callBack.loginError("失败啦");        }    }}
  • 3、view层和model层都准备好了,看看presenter怎么联系他俩吧

还是先把刚刚说的那个回调的接口展示给大家吧

public interface LoginCallBack {    void loginSuccess(String data);    void loginError(String error);}

控制view和model的presenter接口

public interface LoginMVP {    void loginMV();}

重点喽,我门看看到底是怎么操作View和model的

要记得同时也要实现回调的接口,要不操作了没有任何的反应,那就白弄了。

public class LoginMVPim implements LoginMVP ,LoginCallBack{    private LoginViewInterface viewInterface;    private UserModelInterfaceIm userModelInterfaceIm;    //操作view和model就要有着两个的对象,看清楚哈一个是接口,一个是接口的实现类    public LoginMVPim(LoginViewInterface viewInterface) {        this.viewInterface = viewInterface;        userModelInterfaceIm = new UserModelInterfaceIm();    }    @Override    public void loginMV() {        viewInterface.showProgress();        viewInterface.changeButtonText("已经点击");        userModelInterfaceIm.login(viewInterface.getUsername(),viewInterface.getPassword(),this);    }    @Override    public void loginSuccess(String data) {        viewInterface.hindProgress();        Log.e("------------>","data"+data);    }    @Override    public void loginError(String error) {        viewInterface.hindProgress();        Log.e("---------->","error"+error);    }}

大概就是这样了,还是要自己一点点的去领悟

我的理解和学习过程
这里写图片描述

这里写图片描述

这里写图片描述

参考文章:
Android中的MVP模式,带实例

浅谈 MVP in Android

源码下载