版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1341970
最近在做项目的时候,刚开始没有考虑空界面,错误界面的处理,一开始是想为每个界面在布局文件中都天剑一个错误界面,空界面,但仔细一想,这样的工作量太大了,而且也不方便处理,于是我想能不能做出一个自定义控件出来,想了听就,终于做出来了,现在将其分享出来,有什么不足的请各位指点。
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() { @Override public 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的成功界面一般是变异羊的,我们交给子类自己去实现
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; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContext=getActivity(); mActivity=getActivity(); if (mLoadingPage == null) { // 之前的frameLayout 已经记录了一个爹了 爹是之前的ViewPager mLoadingPage = new LoadingPage(this.mContext) { @Override public View createSuccessView() { return BaseFragment.this.createSuccessView(); } }; } else { ViewUtils.removeParent(mLoadingPage);// 移除frameLayout之前的爹 } return mLoadingPage; // 拿到当前viewPager 添加这个framelayout } @Override public 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 { @Override public View createSuccessView() { return View.inflate(mContext,R.layout.fragemnt_test,null); } @Override protected void initData() { mLoadingPage.postDelayed(new Runnable() { @Override public void run() { show(LoadingPage.LoadResult.error); } },2500); }}
我们可以看到我们所做的就是创建自己的成功界面,如果想显示别的界面,就调用void show(LoadResult loadResult)这个方法,这个我们延时之后调用 show(LoadingPage.LoadResult.error);来显示错误界面
public class EmptyFragment extends BaseFragment { @Override public View createSuccessView() { return View.inflate(mContext,R.layout.fragemnt_test,null); } @Override protected void initData() { mLoadingPage.postDelayed(new Runnable() { @Override public 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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); initWindows(); // base setup mContext = this; if (mLoadingPage == null) { mLoadingPage = new LoadingPage(this) { @Override public 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)这个方法而已