运用UILoader处理UI异常流显示

在一个成熟的安卓项目中,我们需要时刻关注app的运行状态,并且根据状态显示相应的UI界面,必须网络中断,内容为空等等。因此一个好的UILoader界面非常重要,下面通过一个简单的例子定义一个UILoader


一、UILoader是什么?

1、UILoader是app运行状态的结果集,在数据流异常的时候可以做到及时展示,通过实现里面的方法,也可以自定义实现相关的调用ui显现。
一般有以下状态:网络错误(点击重试),内容为空,正在加载,成功加载等状态,如下图

fragmet_error_view在这里插入图片描述
fragmet_empty_view在这里插入图片描述
fragmet_loading_view在这里插入图片描述

二、UILoaded定义

1.UILoaded

代码如下(示例):

public abstract  class UILoader extends FrameLayout {

    private View mLoadingView;
    private View mSuccessView;
    private View mNetWorkErrorView;
    private View mEmptyView;
    private  OnRetryClickListener mOnRetryClickListener=null;

    public enum UIState{
        //定义4个状态 加载中,成功时,网络错误时,内容为空时
        LOADING,SUCCESS,NETWORK_ERROR,EMPTY,NONE
    }
    //当前状态
    public UIState mCurrentStatus=UIState.NONE;
    
    //为了方便,统一在同一个构造方法中进行初始化
    public UILoader(@NonNull Context context) {
        this(context,null);
    }

    public UILoader(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public UILoader(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }
    //init UI
    private void init() {
        switchUIByCurrentStates();
    }
    //先初始化载入相应的状态View,并根据状态设置是否可以可见
    private void switchUIByCurrentStates() {
        //Loading
        if(mLoadingView==null) {
            mLoadingView = getLoadingView();
            addView(mLoadingView);
        }
        // change visibility by states
        mLoadingView.setVisibility(mCurrentStatus==UIState.LOADING ? VISIBLE : GONE);
        //Success
        if(mSuccessView==null) {
            mSuccessView = getSuccessView(this);
            addView(mSuccessView);
        }
        // change visibility by states
        mSuccessView.setVisibility(mCurrentStatus == UIState.SUCCESS ? VISIBLE : GONE);
        //netWork worring

        if(mNetWorkErrorView ==null) {
            mNetWorkErrorView  = getNetWorkErrorView();
            addView(mNetWorkErrorView);
        }
        // change visibility by states
        mNetWorkErrorView .setVisibility(mCurrentStatus==UIState.NETWORK_ERROR ? VISIBLE : GONE);

        //date is null
        if(mEmptyView ==null) {
            mEmptyView = getEmptyView();
            addView(mEmptyView);
        }
        // change visibility by states
        mEmptyView .setVisibility(mCurrentStatus==UIState.EMPTY ? VISIBLE : GONE);






    }
    //当状态改变的时候,也要及时变更ui的状态
    public void updateStatus(UIState status){
        mCurrentStatus=status;
        //update ui in main thread
        BaseApplication.getsHandler().post(new Runnable() {
            @Override
            public void run() {
                switchUIByCurrentStates();
            }
        });
    }
    //载入内容为空的View,具体的ui可以自定义,这里设置为fragmet_empty_view
    protected View getEmptyView() {
        return LayoutInflater.from(getContext()).inflate(R.layout.fragmet_empty_view,this,false);
    }
    //载入网络错误的View,具体的ui可以自定义,这里为fragmet_error_view
    private View getNetWorkErrorView() {
        View netWorkError=LayoutInflater.from(getContext()).inflate(R.layout.fragmet_error_view,this,false);
        netWorkError.findViewById(R.id.network_error_icon).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //reflash
                if (mOnRetryClickListener != null) {
                    mOnRetryClickListener.onRetryClick();
                }

            }
        });

        return netWorkError;
    }
    //由于成功时的状态是多变的,我门先定义为抽象方法,由调用者去实现相关的ui显示
    protected abstract View getSuccessView(ViewGroup viewGroup);
    //载入正在加载的View,具体的ui可以自定义,这里为fragmet_loading_view
    private View getLoadingView() {
        return LayoutInflater.from(getContext()).inflate(R.layout.fragmet_loading_view,this,false);
    }
    
    //网络错误时淫才可以点击重试,所以定义如下的接口,由调用者去实现相关的点击方法
    public  void setOnRetryClickListener(OnRetryClickListener listner){
        this.mOnRetryClickListener=listner;
    }

    public interface OnRetryClickListener{
        void onRetryClick();

    }
}

2.运用UILoader

代码如下(示例):

        if (mUiLoader == null) {
            mUiLoader = new UILoader(this) {
             // 实现成功时的View
                @Override
                protected View getSuccessView(ViewGroup viewGroup) {
                    return createSuccessView(viewGroup);
                }
            };
            mDetailListContainer.removeAllViews();
            //为了接下来的状态改变,我们应该移除已经载入的uiLoader的子View
            //mDetailListContainer为调用uiload的容器
            
            mDetailListContainer.addView(mUiLoader);
            mUiLoader.setOnRetryClickListener(DetailActivity.this);
        }

最后当需要改变ui的状态的时候,直接调用

UiLoader.updateStatus(UILoader.UIState.状态码);

注意,如果需要在网络中断的时候点击重试,应该还要设置setOnRetryClickListener方法。并实OnRetryClickListener的方法细节


总结

通过UILoader我们可以做到重构多余的UI更改代码,通过实现getSuccessView方法,去自定义处理成功界面的显现,做到一码多用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值