MVP框架搭建(2):mvp的分块演示
2018-03-22 本文已影响565人
tmyzh
上一篇主要讲mvp的概念,怎么将原来一个activity分成model,presenter,activity三部分,不熟悉的可以点击下面链接
MVP框架搭建(1):界面数据分离
这一片主要讲如何将封装三部分的基类,以及演示三部分如何串联起来。
BaseView
当presenter收到网络返回的响应时,通过baseView传递给activity更新界面
public interface DaggerBaseView {
/**
* 显示网络请求加载转圈
*/
void showLoading();
/**
* 关闭加载转圈
*/
void hideloading();
/**
* 吐息一些信息
* @param msg
*/
void showToast(String msg);
void showErr();
Context getContext();
}
BaseModel
采用了泛型,防止因为数据类型不一致导致创建多个model的基类
public interface DaggerBaseModel <T>{
/**
* 创建接口对象
*/
void getNetApi();
/**
* 发送get请求
* @param callback
*/
void requestGetAPI( BaseCallBack<T> callback);
/**
* 发送post请求
* @param params
* @param callBack
*/
void requestPostAPI( Map params, BaseCallBack<T> callBack);
BasePresenter
也用到了泛型,因为每个Presenter里都需要一个View对象,所以用了一个继承BaseView的泛型对象
public abstract class DaggerBasePresenter<V extends DaggerBaseView,T> implements BaseCallBack<T> {
private V mvpView;
/**
* 绑定view,在获取网络响应之后通过view传递给activity
* @param mvpView
*/
public void attachView(V mvpView){
this.mvpView=mvpView;
}
/**
* 解绑view
*/
public void detachView(){
this.mvpView=null;
}
/**
* 判断是否解绑 在网络请求时页面被终结,导致后续出现nullpointException
* @return
*/
public boolean isViewAttached(){
return mvpView!=null;
}
public V getMvpView(){
return mvpView;
}
/**
* 在页面对象创建完成后调用,可以用来初始化数据层对象
*/
public abstract void onStart();
}
BaseActivity
使用了一个presenter的泛型,一个view的泛型, 每个逻辑不同的页面要生成不同的view和presenter
public abstract class DaggerBaseActivity<V extends DaggerBaseView,T extends DaggerBasePresenter> extends Activity implements DaggerBaseView {
protected T presenter;
private ProgressDialog progressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutRes());
//将当前activity加入自定义的app管理中
AppManager.getInstance().addActivity(this);
presenter=creatPresenter();
if(presenter!=null){
//绑定当前页面的view,用于presnter获取数据之后控制activity的变化
presenter.attachView((V)this);
}
ButterKnife.bind(this);
progressDialog=new ProgressDialog(this);
progressDialog.setCancelable(false);
init(savedInstanceState);
if(presenter!=null){
presenter.onStart();
}
}
/**
* 做一些初始化操作
* @param savedInstanceState
*/
protected abstract void init(Bundle savedInstanceState);
/**
* 指定需要加载的布局文件
* @return
*/
protected abstract int getLayoutRes();
/**
* 创建presenter对象
*/
protected abstract T creatPresenter();
/**
* 使用presenter对象
* @return
*/
public T getPresnter(){
return presenter;
}
@Override
public void showLoading() {
progressDialog.show();
}
@Override
public void hideloading() {
progressDialog.hide();
}
@Override
public void showToast(String msg) {
Toast.makeText(getContext(),msg,Toast.LENGTH_SHORT).show();
}
@Override
public void showErr() {
Toast.makeText(getContext(),"出错",Toast.LENGTH_SHORT).show();
}
@Override
public Context getContext() {
return DaggerBaseActivity.this;
}
@Override
protected void onDestroy() {
super.onDestroy();
if(presenter!=null){
presenter.detachView();
}
presenter=null;
AppManager.getInstance().finishActivity(this);
}
}
需要导入的三方依赖
compile 'com.jakewharton:butterknife:7.0.1'
//rxjava与retrofit
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.7'
// Android 支持 Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
// 衔接 Retrofit & RxJava
// 此处一定要注意使用RxJava2的版本
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
// 支持Gson解析
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
下面展示一个例子,演示怎么使用
api接口 这里用到是爱词霸的公开接口做测试,大家可以在网上查找
public interface GetDatas {
@GET(Urls.test)
Observable<Translation> getCall();
}
model实现获取网络数据的方法
public class YoudaoDataModel implements DaggerBaseModel<String> {
GetDatas getDatas;
@Override
public void getNetApi() {
getDatas= ApiFactory.getInstance().create(GetDatas.class);
}
@Override
public void requestGetAPI(final BaseCallBack<String> callback) {
getDatas.getCall()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("yzh","onSubscribe");
}
@Override
public void onNext(Translation translation) {
Log.e("yzh","oNext--"+translation.show());
callback.onSuccess(translation.show());
}
@Override
public void onError(Throwable e) {
Log.e("yzh","onError--"+e.getMessage());
callback.onFailure(e.getMessage());
}
@Override
public void onComplete() {
Log.e("yzh","onComplete--");
callback.onComplete();
}
});
}
@Override
public void requestPostAPI( Map params, BaseCallBack<String> callBack) {
}
view继承基类,添加当前页面需要的额外方法
public interface YouDaoView extends DaggerBaseView {
/**
* 加载网络请求回来的数据
* @param msg
*/
void showNetData(String msg);
}
presenter现在在基类中是实现callback,在具体页面时用泛型传递具体的数据类型,之前是在网络请求的时候直接new一个callback,还没对比出哪个更好一些
public class YouDaoPresenter extends DaggerBasePresenter<YouDaoView,String> {
private YoudaoDataModel youdaoDataModel;
@Override
public void onStart() {
youdaoDataModel=new YoudaoDataModel();
youdaoDataModel.getNetApi();
}
public void getNetData(){
if(!isViewAttached()){
//已经解绑了
return;
}
getMvpView().showLoading();
youdaoDataModel.requestGetAPI(this);
}
@Override
public void onSuccess(String data) {
if(isViewAttached()){
getMvpView().showNetData(data);
}
}
@Override
public void onFailure(String msg) {
if(isViewAttached()){
getMvpView().showToast(msg);
getMvpView().hideloading();
}
}
@Override
public void onError() {
if(isViewAttached()){
getMvpView().hideloading();
getMvpView().showErr();
}
}
@Override
public void onComplete() {
if(isViewAttached()){
getMvpView().hideloading();
}
}
Activity
public class YoudaoActivity extends DaggerBaseActivity<YouDaoView,YouDaoPresenter> implements YouDaoView {
@Bind(R.id.tv_get_data)
TextView tv_get_data;
@Bind(R.id.tv_data)
TextView tv_data;
@Override
public void showNetData(String msg) {
tv_data.setText(msg);
}
@Override
protected void init(Bundle savedInstanceState) {
}
@Override
protected int getLayoutRes() {
return R.layout.activity_youdao;
}
@Override
protected YouDaoPresenter creatPresenter() {
return new YouDaoPresenter();
}
@OnClick(R.id.tv_get_data)
public void getNetData(){
presenter.getNetData();
}
}
演示效果
。。。。gif传不上去,各位看官就自行code吧
下一步会优化网络请求方式这一块,包括返回数据结构的优化,大家可以看到这些类都带了一个Dagger,没错我就是要用Dagger做解耦,但是我好像在入门到放弃的道路上越走越远了