Weli收藏的文章AndroidandroidAndroid控件

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做解耦,但是我好像在入门到放弃的道路上越走越远了

上一篇 下一篇

猜你喜欢

热点阅读