转载地址:http://www.jianshu.com/p/14283d8d3a60
15年年底本人公司新开的一个项目,用上了mvp模式开发,那个时候还没发现google出了mvp的demo。
网络接口请求用户信息之前 获得userId,然后展示loading,数据加载成功取消loading,最后将数据展示在Activity上
3:Presetner--UserInfoPresenter:这里就实现一个模拟的接口请求 public class UserInfoPresenter { private IUserInfoView iUserInfoView; public UserInfoPresenter(IUserInfoView iUserInfoView) { this.iUserInfoView = iUserInfoView; } public void loadUserInfo() { String userId = iUserInfoView.loadUserId(); iUserInfoView.showLoading();//接口请求前显示loading //这里模拟接口请求回调- new Handler().postDelayed(new Runnable() { @Override public void run() { //模拟接口返回的json,并转换为javaBean UserInfoModel userInfoModel = new UserInfoModel("小宝", 1, "杭州"); iUserInfoView.showUserInfo(userInfoModel); iUserInfoView.dismissloading(); } }, 3000); } } 4:View--UserInfoActivity实现IUserInfoView接口: public class UserInfoActivity extends AppCompatActivity implements IUserInfoView { private TextView tv_name; private TextView tv_age; private TextView tv_address; private UserInfoPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_name = (TextView) findViewById(R.id.tv_name); tv_age = (TextView) findViewById(R.id.tv_age); tv_address = (TextView) findViewById(R.id.tv_address); presenter = new UserInfoPresenter(this); presenter.loadUserInfo(); } @Override public void showLoading() { Toast.makeText(this, "正在加载", Toast.LENGTH_LONG).show(); } @Override public void dismissLoading() { Toast.makeText(this, "加载完成", Toast.LENGTH_LONG).show(); } @Override public void showUserInfo(UserInfoModel userInfoModel) { if (userInfoModel != null) { tv_name.setText(userInfoModel.getName()); tv_age.setText(String.valueOf(userInfoModel.getAge())); tv_address.setText(userInfoModel.getAddress()); } } @Override public String loadUserId() { return "1000";//假设需要查询的用户信息的userId是1000 } }这里多了一个contract包:里面放的是契约接口。更能直接明了的看到View和Presenter之间的方法。 还多了一个BaseView,BasePresenter:看代码
public interface BasePresenter { void start(); }这里的start()方法就相当于约定了所有的Presenter的初始化操作都放在start()方法中;
public interface BaseView<T> { void setPresenter(T presenter); } 再来看契约类:UserInfoContract 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(); } }契约内部有2个接口,分别继承了BaseView和BasePresenter,View和Presenter中实现的方法分别是UI操作,和数据业务逻辑操作,此时是不是看的异常的清晰。
多了一个契约类,契约内部包含了2个接口,一个是Presenter一个是View,就相当于之前的写法中的接口IView和普通类Presenter,只不过现在都将这两个类所需要的业务和UI层的接口直接放在一起展现出来,变得很清晰。在契约接口中的Presenter是一个接口,需要我们去实现,代码如下:
public class UserInfoPresenter implements UserInfoContract.Presenter { private UserInfoContract.View view; public UserInfoPresenter(UserInfoContract.View view) { this.view = view; view.setPresenter(this); } @Override public void loadUserInfo() { String userId = view.loadUserId(); view.showLoading();//接口请求前显示loading //这里模拟接口请求回调- new Handler().postDelayed(new Runnable() { @Override public void run() { //模拟接口返回的json,并转换为javaBean UserInfoModel userInfoModel = new UserInfoModel("小宝", 1, "杭州"); view.showUserInfo(userInfoModel); view.dismissLoading(); } }, 3000); } @Override public void start() { loadUserInfo(); } }1:UserInfoPresenter 构造函数中传入UserInfoContract.View,并且调用view的setPresenter()方法; 2:将所有的初始化操作都放在start()方法中(这里demo只有一个:网络请求获取用户信息),这样只要进入界面的时候调用start()方法就可以执行一系列初始化的操作,这就相当于一种约定好的开发。
最后看UserInfoActivity如何进行调用 public class UserInfoActivity extends AppCompatActivity implements UserInfoContract.View { private TextView tv_name; private TextView tv_age; private TextView tv_address; private UserInfoContract.Presenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); 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); presenter.start(); } @Override public void showLoading() { Toast.makeText(this, "正在加载", Toast.LENGTH_LONG).show(); } @Override public void dismissLoading() { Toast.makeText(this, "加载完成", Toast.LENGTH_LONG).show(); } @Override public void showUserInfo(UserInfoModel userInfoModel) { if (userInfoModel != null) { tv_name.setText(userInfoModel.getName()); tv_age.setText(String.valueOf(userInfoModel.getAge())); tv_address.setText(userInfoModel.getAddress()); } } @Override public String loadUserId() { return "1000";//假设需要查询的用户信息的userId是1000 } @Override public void setPresenter(UserInfoContract.Presenter presenter) { this.presenter = presenter; } }在onCreate()方法:
new UserInfoPresenter(this); presenter.start();而并没有写成
presenter=new UserInfoPresenter(this);因为UserInfoActivity实现了UserInfoContract.View中的setPresenter()方法;而UserInfoPresenter 构造函数中已经调用了UserInfoContract.View中的setPresenter()方法;
两者思想一样,只是写法不同。 后者demo地址