打造简单的LoadingPageView
2015-11-11 14:13
218 查看
打造简单的LoadingPageView
日常开发中,需要用到耗时操作的页面我们都应该加入等待页面。让用户知道网络正在努力加载,否则用户体验就非常差。1.等待页面的两种方式
第一种:
一种是show一个dialog。就像下图这样这种等待页面一般把dialog设置为不可取消的,防止在执行重要的操作的时候用户重复点击或者错误操作。比如支付宝支付的时候……
这种方式做起来比较简单,无非就是自定义一个dialog而已。耗时操作的时候show出来,完毕的时候dismiss就可以了。
第二种:
还有一种方式就是单纯的页面层叠,有点像PS中的图层=。=,很难描述,直接看图吧。其实是四个页面叠在一起,不同情况显示不同的页面(Visiable和InVisiable)
用这种方式的好处是可以不让用户看到默认页面,比如你写一个布局,里面的数据都是假的,网络请求访问成功后才会刷新真实数据。你不想让用户看到假数据,这时候就可以用这种方式,并且是可以按返回键的=。=
loding
empty
error
如上三个图, 分别对应的是等待的时候,返回数据错误的时候,还有网络连接错误的时候。 当然,还有就是请求成功的时候就该显示出正常的页面给用户看了……
今天这博客就专门写第二种方式的简单实现原理,第一种就不赘述了。
2.实现LoadingPageView
其实原理很简单,我们只需要用一个FrameLayout或者RelativeLayout里面写上四个布局,根据需求Visiable和Invisiable了。但是这样做的话,你的重复代码就很了,因为Loading,empty,error页面来来去去就这么三个,所以我们可以抽出来。
1. 首先将Loading,Empty,Error页面画出来
Loding页面<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar android:layout_width="35dp" android:layout_height="35dp" android:layout_gravity="center" style="@style/Widget.AppCompat.ProgressBar" /> </FrameLayout>
Empty页面
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="100dp" android:layout_height="100dp" android:scaleType="centerInside" android:layout_gravity="center" android:src="@drawable/ic_empty_page" /> </FrameLayout>
Error页面
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" > <ImageView android:id="@+id/page_iv" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerHorizontal="true" android:scaleType="centerInside" android:src="@drawable/ic_error_page" /> <Button android:id="@+id/page_bt" android:layout_width="wrap_content" android:layout_height="34dp" android:layout_below="@id/page_iv" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:background="@drawable/btn_bg" android:ellipsize="end" android:paddingLeft="10dp" android:paddingRight="10dp" android:singleLine="true" android:text="加载失败,点击重试" android:textColor="#ff717171" android:textSize="14dp" /> </RelativeLayout> </FrameLayout>
2.LoadingPageView的完整代码
/** * Created by AItsuki on 2015/11/5. */ public class LoadingPageView extends FrameLayout { private static final int STATE_UNLOADED = 0;//未知状态 private static final int STATE_LOADING = 1;//加载状态 private static final int STATE_ERROR = 2;//加载完毕,但是出错状态 private static final int STATE_EMPTY = 3;//加载完毕,但是没有数据状态 private static final int STATE_SUCCEED = 4;//加载成功 private int mState; private Context mContext; private View mLoadingView; private View mErrorView; private View mEmptyView; private View mSuccessView; private Button page_bt; private Reloadable reloadable; private int flag; public LoadingPageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; flag = 1; init(); } public LoadingPageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public LoadingPageView(Context context) { super(context); this.mContext = context; init(); } /** * 初始化 */ private void init() { mState = STATE_UNLOADED; // 初始化状态 reloadable = new Reloadable() { @Override public void reload() { } }; } /** * 设置成功的页面 * * @param view */ public void setSuccessView(View view) { // 创建相对应的view // 加载中页面 mLoadingView = inflate(mContext, R.layout.loading_page_loading, null); addView(mLoadingView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); // 加载失败页面 mErrorView = inflate(mContext, R.layout.loading_page_error, null); page_bt = (Button) mErrorView.findViewById(R.id.page_bt); page_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { reset(); reloadable.reload(); } }); addView(mErrorView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); // 加载成功,服务器没有数据页面 mEmptyView = inflate(mContext, R.layout.loading_page_empty, null); addView(mEmptyView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); mSuccessView = view; // 成功页面 addView(mSuccessView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); showPage(); } /** * @param reloadable */ public void setReloadable(Reloadable reloadable) { this.reloadable = reloadable; } /** * 显示页面 */ private void showPage() { Log.e("LoadingPage", "showPage =================" + mState); if (null != mLoadingView) { mLoadingView.setVisibility(mState == STATE_UNLOADED || mState == STATE_LOADING ? View.VISIBLE : View.INVISIBLE); } if (null != mErrorView) { mErrorView.setVisibility(mState == STATE_ERROR ? View.VISIBLE : View.INVISIBLE); } if (null != mEmptyView) { mEmptyView.setVisibility(mState == STATE_EMPTY ? View.VISIBLE : View.INVISIBLE); } if (null != mSuccessView) { mSuccessView.setVisibility(mState == STATE_SUCCEED ? View.VISIBLE : View.INVISIBLE); } } private void reset() { mState = STATE_UNLOADED; showPage(); } /** * 设置状态,并且显示相对应的页面 * * @param state */ public void setState(State state) { this.mState = state.getValue(); showPage(); } /** * 页面状态 */ public enum State { ERROR(2), EMPTY(3), SUCCEED(4); int value; State(int value) { this.value = value; } public int getValue() { return value; } } public interface Reloadable { void reload(); } @Override protected void onFinishInflate() { super.onFinishInflate(); if(flag == 1) { FrameLayout frameLayout = new FrameLayout(mContext); int childCount = getChildCount(); for (int i=0 ; i<childCount; i++) { View view = getChildAt(i); removeView(view); frameLayout.addView(view); } setSuccessView(frameLayout); } } }
3. LoadingPageView使用方式
还是看demo吧,有点累=。=有两种使用方式,一种是在布局文件中(推荐),另一种是在代码中直接new出来。
Demo中使用到了张鸿洋张鸿洋大神封装的okhttpClient工具类,点这里跳转。
下载地址:http://download.csdn.net/detail/u010386612/9260393
相关文章推荐
- 正则表达式之旅_sed_awk
- HttpURLConnection--HttpURLConnection的Get请求方式
- android context提供的openFileInput()方法
- Android项目工程目录详解
- iOS 获取本地视频播放路径
- 互联网+“变”与“不变”首届本土管理实践与创新论坛
- error LNK2001 无法解析的外部符号
- 重写与重载简单例子区分
- 如何提问才能进阶成为前端大神?--正确的邮件提问方式
- 最多约数问题
- esri/dijit/andlysis/ExtractData:给定的extent提取数据
- 程序员应该坚决避免的十种编程坏毛病
- [17]AWK记录、字段、模式、跨平台移植及正则表达式
- Jquery弹出Alert,Confirm,Prompt对话窗
- 从各个数据集中整合2004-2010年的疟疾数据
- 为什么要从Web form过渡到MVC中
- BootStrap学习(7)_轮播图
- 数据链表+算法汇总一
- php中比较好用的函数
- 如何将liquibase部署到tomcat服务器上(使用postgresql数据库)