打造简单的LoadingPageView

打造简单的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

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值