您的位置:首页 > 其它

打造简单的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: