android快速开发系列

来源:互联网 发布:excel会计记账软件 编辑:程序博客网 时间:2024/06/07 00:35

项目基本框架搭架时的一些抽取:

其实任何应用就只有4种页面: 1.加载页面    2.错误页面    3.空页面    4.成功页面

对于前3种页面基本都是固定的, 属于常规页面, 而成功页面是需要根据实际情况做显示的.进入应用首先会显示加载页面, 在加载完数据之后, 才能判断出显示哪个具体页面.其实我们可以使用MVC模式来做控制, 现在M, V已经都有了, 那么还缺少一个C, 现在就开始动手吧, 我们准备创建类继承FrameLayout来作为控制类:

public abstract class LoadingPager extends FrameLayout {private ViewmLoadingView;private ViewmErrorView;private ViewmEmptyView;private ViewmSuccessView;public static final intSTATE_NONE= -1;// 默认状态public static final intSTATE_LOADING= 0;// 加载中public static final intSTATE_ERROR= 1;// 错误public static final intSTATE_EMPTY= 2;// 空public static final intSTATE_SUCCESS= 3;// 成功public intmCurState= STATE_NONE;public LoadingPager(Context context) {super(context);initCommonView();}/** * @des 初始化常规视图① 加载页面② 错误页面③ 空页面 * @call LoadingPager初始化的时候被调用 */private void initCommonView() {// ① 加载页面mLoadingView = View.inflate(UIUtils.getContext(), R.layout.pager_loading, null);this.addView(mLoadingView);// ② 错误页面mErrorView = View.inflate(UIUtils.getContext(), R.layout.pager_error, null);this.addView(mErrorView);// ③ 空页面mEmptyView = View.inflate(UIUtils.getContext(), R.layout.pager_empty, null);this.addView(mEmptyView);refreshUIByState();}/** * @des 根据当前的状态显示不同的视图 * @call 1.LoadingPager初始化的时候被调用 * @call 2.正在开始加载前,重置当前状态,会刷新ui * @call 3.数据加载完成之后被调用 */private void refreshUIByState() {// 控制加载页面的显示/隐藏mLoadingView.setVisibility((mCurState == STATE_LOADING) || (mCurState == STATE_NONE) ? 0 : 8);// 控制错误页面的显示/隐藏mErrorView.setVisibility((mCurState == STATE_ERROR) ? 0 : 8);// 控制空页面的显示/隐藏mEmptyView.setVisibility((mCurState == STATE_EMPTY) ? 0 : 8);if (mSuccessView == null && mCurState == STATE_SUCCESS) {mSuccessView = initSuccessView();this.addView(mSuccessView);}if (mSuccessView != null) {// 控制成功页面的显示/隐藏mSuccessView.setVisibility((mCurState == STATE_SUCCESS) ? 0 : 8);}}// 数据加载的流程/**① 触发加载  进入页面开始加载/点击某一个按钮的时候加载② 异步加载数据  -->显示加载视图③ 处理加载结果① 成功-->显示成功视图② 失败① 数据为空-->显示空视图② 数据加载失败-->显示加载失败的视图*/// ① 触发加载public void triggerLoadData() {if (mCurState != STATE_SUCCESS && mCurState != STATE_LOADING) {LogUtils.sf("###开始加载中");// ② 异步加载数据// 加载开始前,重置状态为加载中int state = STATE_LOADING;mCurState = state;refreshUIByState();// new Thread(new LoadDataTask()).start();ThreadFactory.getNormalPool().execute(new LoadDataTask());}}class LoadDataTask implements Runnable {@Overridepublic void run() {// 子线程中// 真正的开始加载数据// 加载数据数据之后-->返回一个临时状态int tempState = initData().getState();// 临时状态==当前的状态mCurState = tempState;UIUtils.postTaskSafely(new Runnable() {@Overridepublic void run() {// 再次刷新视图显示refreshUIByState();}});}}/** * @des 真正子子线程中加载数据,必须实现,但是不知道具体实现,交给子类去实现 * @call triggerLoadData方法被调用的时候调用 */protected abstract LoadedResult initData();/** * @des 数据加载成功的时候返回具体的成功视图,必须实现,但是不知道具体实现,交给子类实现 * @call 数据加载成功的时候 */protected abstract View initSuccessView();public enum LoadedResult {SUCCESS(STATE_SUCCESS), EMPTY(STATE_EMPTY), ERROR(STATE_ERROR);intmState;public int getState() {return mState;}private LoadedResult(int state) {mState = state;}}}
OK, 我再贴上BaseFragment的代码, 我们可以创建子类来完成具体的显示:

public abstract class BaseFragment extends Fragment {private LoadingPagermLoadingPager;public LoadingPager getLoadingPager() {return mLoadingPager;}@Overridepublic boolean getUserVisibleHint() {// 类似我们fragment里面的onresume/* mLoadingPager.triggerLoadData();*/return super.getUserVisibleHint();}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {if (mLoadingPager == null) {// 第一次mLoadingPager = new LoadingPager(UIUtils.getContext()) {@Overrideprotected LoadedResult initData() {return BaseFragment.this.initData();}@Overrideprotected View initSuccessView() {return BaseFragment.this.initSuccessView();}};} else {// 第2次ViewParent parent = mLoadingPager.getParent();if (parent != null && parent instanceof ViewGroup) {((ViewGroup) parent).removeView(mLoadingPager);}}// 盒子里面的一个BaseFragment取出来-->取出里面的mLoadingPager-->返回给viewPager-->adapter-->Fragmentreturn mLoadingPager;// -->view-->ViewGroup}// 页面显示分析// Fragment/Activity共性-->页面共性-->视图的展示/** 任何应用其实就只有4种页面类型-->常规的页面 ① 加载页面 ② 错误页面 ③ 空页面   ④ 成功页面 ①②③三种页面一个应用基本是固定的每一个fragment/activity对应的页面④就不一样进入应用的时候显示①,②③④需要加载数据之后才知道显示哪个*/// 数据加载的流程/**① 触发加载  进入页面开始加载/点击某一个按钮的时候加载② 异步加载数据  -->显示加载视图③ 处理加载结果① 成功-->显示成功视图② 失败① 数据为空-->显示空视图② 数据加载失败-->显示加载失败的视图*//** * @des 真正子子线程中加载数据,必须实现,但是不知道具体实现,交给子类去实现 * @des 它是和LoadingPager中的initData同名方法 * @call triggerLoadData方法被调用的时候调用 */protected abstract LoadedResult initData();/** * @des 数据加载成功的时候返回具体的成功视图,必须实现,但是不知道具体实现,交给子类实现 * @des 它是和LoadingPager中的initSuccessView同名方法 * @call 数据加载成功的时候 */protected abstract View initSuccessView();/** * 检测加载网络之后返回数据对应的状态 * @param obj * @return */public LoadedResult checkState(Object obj) {if (obj == null) {return LoadedResult.EMPTY;}// listif (obj instanceof List) {if (((List) obj).size() == 0) {return LoadedResult.EMPTY;}}// mapif (obj instanceof Map) {if (((Map) obj).size() == 0) {return LoadedResult.EMPTY;}}return LoadedResult.SUCCESS;}}
未完待续。。。。。。。。。。。吐舌头吐舌头

0 0
原创粉丝点击