摘要: 通过上面三篇文章所提到的关于MVP框架的封装,我们已经能够大大简化MVP模式中MP层的开发流程。但是还有一个问题,就是在开发的时候我们的 View层组件还需要处理较多的事情,例如错误处理,进度条显示等。所以我们需要对View层的组建进行封装,优化开发的流程。
对View组建进行优化
笔者根据封装好的MVP的特点,对View层的组建进行了不同的封装。里面包含2个Activity、两个Fragment和一个Adapter基类。它们的名称分别是:MvpActivity 、MvpListActivity、MvpFragment、MvpListFragment、BaseListAdapter。它们的目的都是为了优化项目的代码和结构,加快项目的开发速度。
在这里笔者只对MvpActivity 这个类进行解析,其他的可以通过查看笔者github上的源码来学习实现方式。MvpActivity中封装了前面我们提到的一些公共方法,它的作用是结合我们前面封装好的BasePresenter使用,实现对项目进行优化的目的。使用普通的presenter获取数据的activity可以通过继承这个类来减少需要自己手动实现的代码。
如果读者想进一步了解其他几个组件的具体实现的话,请到笔者的github上下载。
处理Toolbar
笔者在开发这个框架的时候是采用Material Design风格进行开发的,采用这个风格进行开发的时候会有一个问题,就是每个Activity都需要重新实现一个toolbar。所以对Activity进行优化的第一项任务就是解决这个问题。
我们先来看看MvpActivity的界面实现:
activity_mvp.xml:
|
|
上面的代码和我们平时的Material Design页面布局时一样的。下面我们来看下content_mvp
的代码:
|
|
从布局可以看到,content_mvp
中包含了SwipeRefreshLayout、ProgressBar、和显示错误的layout等。那么是如何实现让子Activity不需要处理toolbar的呢?笔者这里用了个简单暴力的办法。你看见上面布局中的FrameLayout了吗?看见了对吧?我就是用FrameLayout的addView方法把子Activity中的布局加进去的。
就好像下面这样:
|
|
这个onCreateView就是在子Activity中需要实现的方法,和fragment的onCreateView使用方法是一样的。而contentViewGroup就是我们上面说的fragment。
这样就可以通过MvpActivity基类简化这一步操作。
实现IMvpActivity接口
IMvpActivity的代码如下:
|
|
IMvpActivity继承了IActivity接口,下面我们来看看IActivity接口的代码
IActivity:
|
|
上面的两个接口中大部分方法都十分简单,只是对activity执行一些初始化操作而已。其中setProgressType(int type)方法是用于设置我们在使用presenter发起获取数据请求的时候显示的进度条样式的。在这里笔者定义了三种样式,分别由dialog样式,默认样式和SwipeRefreshLayout样式。这个进度条样式在收到IMvpView
接口的showProgress(final boolean show)的时候会显示/隐藏进度条。
实现IMvpView接口
我们先来看看IMvpView接口的定义:
|
|
|
|
可以看到,这就是我们前面的文章中提到的IBaseView接口,这个接口的主要是用于处理错误回调与进度条的显示/隐藏。
下面我们来看看几个方法的实现:
showProgress(boolean show)
|
|
由于我们已经生成了不同样式的进度条实例,所以我们在这里根据设置的进度条样式来显示具体的进度条。这里需要注意的是,为了更好的人机交互体验,我们要根据不同的进度条样式来选择不同重连机制的处理方式,这里分别实现了点击错误提示重连和下拉重连,更多的实现读者可以自己进行拓展。
showNetworkError和showServerError
|
|
可以看到这两个错误回调的最终实现时onError方法,下面是onError的代码:
|
|
错误信息的展现形式也是和进度条的样式有关的,这样做是为了优化交互体验。下面我们来看看这三种不同设置的实际效果。
对前面文章的补充
前几篇文章中,关于BasePresenter的设计有一个小小的补充,这是由于笔者编写代码的时候的一个小的bug。
错误代码:
|
|
错误的地方在于关于baseModel的调用,在这里我们应该使用getModel获取Model实例。为什么要这样做呢?因为BasePresenter默认使用的是VolleyModle,当在子Presenter需要使用其它类型的Model的时候,可以通过覆盖getModel()这个方法来重设Modle实例。
修改后的代码为:
|
|
小结
限于篇幅,笔者在这里只是对MvpActivity作了一个简单的介绍,但是核心思想是一样的,通过对一些公共方法的封装(不同activity的初始化,错误处理,进度条的现实隐藏都是类似的),实现简化我们的代码的目的。这个项目涉及的技术点较多,但是都是相对简单的,所以笔者在这里就不对其他view组件展开讨论了。