今天要介绍的是github上一个Android开源框架: android-starter-kit (Rx部分)
链接: https://github.com/qijitech/android-starter-kit
Fragment系列:
(一)View与Presenter
(二)NetworkFragment
(三)RecyclerFragment之UI部分
今天要讲和网络相关的fragment: StarterNetworkFragment
这个fragment用到一个类, 这个类负责显示加载中, 显示网络错误等等, 这个类就叫ContentPresenter
ContentPresenter
虽然它也叫presenter, 但要澄清一下, 它并没有继承基础的presenter类, 它其实就是一个独立的类.
先来看构造方法:
public ContentPresenter(Class<View> loadViewClass, Class<View> emptyViewClass, Class<View> errorViewClass) {
buildViewClassArray(loadViewClass, emptyViewClass, errorViewClass);
}
传入参数为 3个 继承view的Class, 从名称可以推断出用在什么地方.
传入之后, 把这3个保存起来.
和上一篇讲到的一样, contentPresenter也是通过注解获取到参数, 然后构造的, 所以要记得写注解~
行, 暂时看到这里, 现在可以看fragment了.
StarterNetworkFragment
先看看类的定义
@RequiresContent public abstract class StarterNetworkFragment<T, P extends Presenter>
extends StarterFragment<P>
implements NetworkContract.ContentInterface<T>,
EmptyView.OnEmptyViewClickListener,
ErrorView.OnErrorViewClickListener
看起来很长, 别急, 我会一个一个解释.
在starterNetworkFragment构造的时候, 会从annotion中读取那3个class, 然后构造一个contentPresenterFactory,
这个factory也很简单, 就是在需要的时候new一个contentPresenter.
onCreate
构造一个contentPresenter, 然后调用contentPresenter的onCreate(Context), contentPresenter会把context保存起来.
然后还会执行
contentPresenter.setOnEmptyViewClickListener(this); contentPresenter.setOnErrorViewClickListener(this);
这2个Listener就是两个方法, 就是说当用户点击这个View的时候应该做什么, 一般就是刷新一下.
值得注意的是, starterNetworkFragment并没有重写这2个方法, 所以它是abstract的, 需要继承者重写.
onResume
这里会把fragment布局的rootview和contentView给contentPresenter保存起来.
这个contentView就是指你的布局的最外层的View, 需要你来提供.
NetworkContract.View接口
(包含在NetworkContract.ContentInterface里面)
这个接口有2个方法, onError和onSuccess.
分别对应网络请求成功和失败的回调
onSuccess什么也没写.
onError里, 调用getContentPresenter().buildEmptyTitle方法, 传入retrofitException的message.
这个方法就要用到构造时传入的emptyViewClass了,
contentPresenter会通过反射来构造, 注意这个emptyViewClass要implement EmptyView这个接口, contentPresenter然后会调用这个emptyView的一些方法.
ProgressInterface接口
(包含在NetworkContract.ContentInterface里面)
有hideProgress(什么也没写)和showProgress.
showProgress就是调用了contentPresenter的displayLoadView方法
现在又要回到contentPresenter了, 先看一波源码:
public ContentPresenter displayLoadView() {
final int loadViewId = LoadViewId;
if (mCurrentId != loadViewId) {
displayView(loadViewId);
}
return this;
}
首先, contentPresenter会先检查是否已经展示了loadView.
再看displayView方法:
private View displayView(@IdRes int viewId) {
//container指最外层的view
final ViewGroup container = mContainer;
//通过viewId找view, 可以看成单例
final View view = checkView(viewId);
//宽和高都是match_parent
final ViewGroup.LayoutParams layoutParams = LayoutHelper.createViewGroupLayoutParams();
container.removeAllViews();
container.addView(view, layoutParams);
mCurrentId = viewId;
return view;
}
(注: 以上源码经过删减)
可以看出, 它通过删除container的内容, 再把loadView添加上去, 这样来显示loadView.
你可能会疑惑, 把内容删掉了, 以后怎么恢复呢?
还记得onResume里, contentPresenter把contentView保存起来, 这样的话其实内容还是在的.
感兴趣可以再看看contentPresenter的displayContentView方法, 同样是把container清空, 再把contentView加上去.
这个fragment就讲到这里, 欢迎看下一篇
(三)RecyclerFragment之UI部分