@xujun94
2016-06-29T10:10:43.000000Z
字数 7343
阅读 1479
自定义View 多界面处理(包括空界面,错误界面,加载中的界面)
最近在做项目的时候,刚开始没有考虑空界面,错误界面的处理,一开始是想为每个界面在布局文件中都天剑一个错误界面,空界面,但仔细一想,这样的工作量太大了,而且也不方便处理,于是我想能不能做出一个自定义控件出来,想了听就,终于做出来了,现在将其分享出来,有什么不足的请各位指点。



package com.szl.loadinngpagedemo.view;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.widget.Button;import android.widget.FrameLayout;import com.szl.loadinngpagedemo.R;/**** 创建了自定义帧布局 把baseFragment 一部分代码 抽取到这个类中** @author itcast*/public abstract class LoadingPage extends FrameLayout {public static final int STATE_UNKOWN = 0;public static final int STATE_LOADING = 1;public static final int STATE_ERROR = 2;public static final int STATE_EMPTY = 3;public static final int STATE_SUCCESS = 4;public int state = STATE_UNKOWN;private Context mContext;private View loadingView;// 加载中的界面private View errorView;// 错误界面private View emptyView;// 空界面private View successView;// 加载成功的界面public LoadingPage(Context context) {this(context,null,0);}public LoadingPage(Context context, AttributeSet attrs) {this(context, attrs,0);}public LoadingPage(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mContext = context;init();}private void init() {loadingView = createLoadingView(); // 创建了加载中的界面if (loadingView != null) {this.addView(loadingView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}errorView = createErrorView(); // 加载错误界面if (errorView != null) {this.addView(errorView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}emptyView = createEmptyView(); // 加载空的界面if (emptyView != null) {this.addView(emptyView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}/*** 注意这里依赖是就初始化成功的界面,也可以在状态成功的时候才初始化成功的界面*/successView = createSuccessView();if(successView!=null){this.addView(successView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}showPage();// 根据不同的状态显示不同的界面}// 根据不同的状态显示不同的界面private void showPage() {if (loadingView != null) {loadingView.setVisibility(state == STATE_UNKOWN|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);}if (errorView != null) {errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE: View.INVISIBLE);}if (emptyView != null) {emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE: View.INVISIBLE);}if (state == STATE_SUCCESS) {if (successView == null) {successView = createSuccessView();this.addView(successView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}successView.setVisibility(View.VISIBLE);} else {if (successView != null) {successView.setVisibility(View.INVISIBLE);}}}/* 创建了空的界面 */private View createEmptyView() {View view = View.inflate(mContext, R.layout.loadpage_empty,null);return view;}/* 创建了错误界面 */private View createErrorView() {View view = View.inflate(mContext, R.layout.loadpage_error,null);Button page_bt = (Button) view.findViewById(R.id.page_bt);page_bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {}});return view;}/* 创建加载中的界面 */private View createLoadingView() {View view = View.inflate(mContext,R.layout.loadpage_loading, null);return view;}/*** 枚举类,对应相应的状态码,用来表示各种状态*/public enum LoadResult {loading(1),error(2), empty(3), success(4);int value;LoadResult(int value) {this.value = value;}public int getValue() {return value;}}/*** 注意请求成功后必须调用show方法,会根据这个压面显示相应的数据* @param loadResult*/public void show(LoadResult loadResult) {state = loadResult.getValue();showPage();}/**** 创建成功的界面** @return*/public abstract View createSuccessView();}
private View loadingView;// 加载中的界面private View errorView;// 错误界面private View emptyView;// 空界面private View successView;// 加载成功的界面errorView = createErrorView(); // 加载错误界面emptyView = createEmptyView(); // 加载空的界面successView = createSuccessView();//加载成功的界面
注意在init()方法里面我们可以知道 createSuccessView()是一个抽象方法,因为每个Activity或Fragment的成功界面一般是变异羊的,我们交给子类自己去实现
2. 接着我们调用showPage()方法根据不同的状态显示不同的界面,默认显示的状态是STATE_UNKOWN,所以显示的状态是
public int state = STATE_UNKOWN;loadingView.setVisibility(state == STATE_UNKOWN|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE: View.INVISIBLE);-------
效果图如下:
**当然我们只需调用void show(LoadResult loadResult)这个方法即可根据相应的状态显示相应的界面
public abstract class BaseFragment extends Fragment {protected LoadingPage mLoadingPage;Context mContext;Activity mActivity;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {mContext=getActivity();mActivity=getActivity();if (mLoadingPage == null) { // 之前的frameLayout 已经记录了一个爹了 爹是之前的ViewPagermLoadingPage = new LoadingPage(this.mContext) {@Overridepublic View createSuccessView() {return BaseFragment.this.createSuccessView();}};} else {ViewUtils.removeParent(mLoadingPage);// 移除frameLayout之前的爹}return mLoadingPage; // 拿到当前viewPager 添加这个framelayout}@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);initData();}protected void initData() {}/**** 创建成功的界面** @return*/public abstract View createSuccessView();public void show(LoadResult loadResult) {if (mLoadingPage != null) {mLoadingPage.show(loadResult);}}/*** 校验数据*/public LoadResult checkData(List datas) {if (datas == null) {return LoadResult.error;// 请求服务器失败} else {if (datas.size() == 0) {return LoadingPage.LoadResult.empty;} else {return LoadingPage.LoadResult.success;}}}}
BaseFragment的代码很简单,就是将我们的LoadPager这个自定义View设置为根布局,然后创建成功的界面由子类自己去实现
public class ErrorFragment extends BaseFragment {@Overridepublic View createSuccessView() {return View.inflate(mContext,R.layout.fragemnt_test,null);}@Overrideprotected void initData() {mLoadingPage.postDelayed(new Runnable() {@Overridepublic void run() {show(LoadingPage.LoadResult.error);}},2500);}}
我们可以看到我们所做的就是创建自己的成功界面,如果想显示别的界面,就调用void show(LoadResult loadResult)这个方法,这个我们延时之后调用 show(LoadingPage.LoadResult.error);来显示错误界面
public class EmptyFragment extends BaseFragment {@Overridepublic View createSuccessView() {return View.inflate(mContext,R.layout.fragemnt_test,null);}@Overrideprotected void initData() {mLoadingPage.postDelayed(new Runnable() {@Overridepublic void run() {show(LoadingPage.LoadResult.empty);}},2500);}}
同理SuccessFragemnt的代码你也能轻易的想象得到,这里就不贴出来了
/*** 博客地址:http://blog.csdn.net/gdutxiaoxu* @author xujun* @time 2016-6-29 14:52.*/public abstract class BaseActivity extends AppCompatActivity {protected Context mContext;protected ProgressDialog dialog;protected LoadingPage mLoadingPage;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);initWindows();// base setupmContext = this;if (mLoadingPage == null) {mLoadingPage = new LoadingPage(this) {@Overridepublic View createSuccessView() {return BaseActivity.this.createSuccessView();}};} else {ViewUtils.removeParent(mLoadingPage);}setContentView(mLoadingPage);dialog = new ProgressDialog(this);initListener();initData();}public void show(LoadingPage.LoadResult loadResult){if(mLoadingPage!=null){mLoadingPage.show(loadResult);}}/*** 创造成功的页面** @return*/protected abstract View createSuccessView();----
思路其实很简单,一开始给LoadPager初始化各种布局,包括错误界面,加载中的界面,空界面,其中成功的界面交友子类自己去实现,如果我们想显示别的界面的话,我们只需要调用void show(LoadResult loadResult)这个方法而已