zoukankan      html  css  js  c++  java
  • Android之自定义LoadingViewHelper

    针对ListView有setEmpty方法来设置加载失败时的默认显示页面,但扩展性太差。有没有通用性更强,适用为任意布局添加加载中等状态布局的方法呢?
    答案是肯定的,接下来我们就去实现这样一个帮助类。申明LoadingViewHelper类,由于加载成功显示的布局为目标显示界面,所以采用构造方法注入。对于加载中以及加载失败显示的布局,申明为抽象方法,由子类决定是否实现,这样增加了扩展性。
    updateLoadingView方法负责根据mLoadingStatus切换显示对应的布局,其中针对View的获取进行了优化,以免重复实例化loadingView和failedView。
    changeLoadingStatus为外界提供访问接口,在业务层可控制显示加载状态对应的View。
    /**
    * Created by Administrator on 2016/6/22.
    * 加载View时各种情况下的View显示
    * 未考虑提示View的宽高超出SucceedView的情况,需要自定义控制非SucceedView的宽高在SuceedView内部
    */
    public abstract class LoadingViewHelper {
    public static final UtilsLog lg = UtilsLogFactory.getLogger(LoadingViewHelper.class);
    private View loadingView;
    private View succeedView;//绑定的布局,用于加载成功时显示
    private View failedView;
    private ViewGroup parentViewGroup;//父布局
    private LoadingStatus mLoadingStatus;//默认为加载中

    /**
    * 不支持SucceedView的父布局为
    *
    * @param succeedView
    */
    public LoadingViewHelper(View succeedView) {
    this.succeedView = succeedView;
    this.parentViewGroup = (ViewGroup) succeedView.getParent();
    if (parentViewGroup == null) {
    //此时succeedView为getDecorView,需要调整
    lg.e("ParentViewGroup is null:当前View为getWindow().getDecorView()");
    this.parentViewGroup = (ViewGroup) (succeedView.findViewById(android.R.id.content));
    this.succeedView = this.parentViewGroup.getChildAt(0);
    }
    this.mLoadingStatus = LoadingStatus.Loading;
    updateLoadingView();
    }

    /**
    * 根据LoadingStatus切换View显示
    */
    private void updateLoadingView() {
    switch (mLoadingStatus) {
    case Loading:
    lg.e("updateLoadingView:Loading");
    if (loadingView == null) {
    loadingView = getLoadingView();
    /*添加至布局中*/
    if (loadingView != null) {
    ViewGroup.LayoutParams layoutParams = succeedView.getLayoutParams();
    parentViewGroup.addView(loadingView, layoutParams);
    }
    }
    settingViewVisibilityIfViewNotNull(loadingView, View.VISIBLE)
    .settingViewVisibilityIfViewNotNull(succeedView, View.GONE)
    .settingViewVisibilityIfViewNotNull(failedView, View.GONE);
    break;
    case Success:
    lg.e("updateLoadingView:Success");
    settingViewVisibilityIfViewNotNull(loadingView, View.GONE)
    .settingViewVisibilityIfViewNotNull(succeedView, View.VISIBLE)
    .settingViewVisibilityIfViewNotNull(failedView, View.GONE);
    break;
    case Faild:
    lg.e("updateLoadingView:Faild");
    if (failedView == null) {
    failedView = getFailedView(succeedView);
    if (failedView != null) {
    ViewGroup.LayoutParams layoutParams = succeedView.getLayoutParams();
    parentViewGroup.addView(failedView, layoutParams);
    }
    }
    settingViewVisibilityIfViewNotNull(loadingView, View.GONE)
    .settingViewVisibilityIfViewNotNull(succeedView, View.GONE)
    .settingViewVisibilityIfViewNotNull(failedView, View.VISIBLE);
    break;
    }
    }

    /**
    * 若View非空,则切换显示方式
    *
    * @param view
    * @param visibility
    * @return
    */
    private LoadingViewHelper settingViewVisibilityIfViewNotNull(View view, int visibility) {
    if (view != null) {
    view.setVisibility(visibility);
    }
    return this;
    }

    /**
    * 切换更新状态
    *
    * @param loadingStatus
    */
    public void changeLoadingStatus(LoadingStatus loadingStatus) {
    if (loadingStatus != null) {
    this.mLoadingStatus = loadingStatus;
    updateLoadingView();
    }
    }

    public enum LoadingStatus {
    Loading, Success, Faild;
    }

    /**
    * 获取加载状态中显示的布局
    *
    * @return
    */
    public abstract View getLoadingView();

    /**
    * 获取加载失败显示的布局
    *
    * @param succeedView
    * @return
    */
    public abstract View getFailedView(View succeedView);
    }
    具体在业务层的使用方式如下,postDelayed模拟请求数据的耗时操作,这里的getFailedView方法中自定义请求重试事件。
    final LoadingViewHelper loadingViewHelper = new LoadingViewHelper(btnActCahngeSkinShowStyle) {
    @Override
    public View getLoadingView() {
    ImageView imageView = new ImageView(getCurActivity());
    imageView.setImageResource(R.mipmap.ic_famer_help_seize);
    imageView.setBackgroundColor(Color.RED);
    return imageView;
    }

    @Override
    public View getFailedView(View succeedView) {
    Button btn = new Button(getCurActivity());
    btn.setText("点击重试");
    btn.setBackgroundColor(Color.YELLOW);
    btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    changeLoadingStatus(LoadingStatus.Loading);
    AppHelper.getInstance().getLooperHandler().postDelayed(new Runnable() {
    @Override
    public void run() {
    changeLoadingStatus(LoadingStatus.Success);
    }
    }, 10000);
    }
    });
    return btn;
    }
    };

    AppHelper.getInstance().getLooperHandler().postDelayed(new Runnable() {
    @Override
    public void run() {
    loadingViewHelper.changeLoadingStatus(LoadingViewHelper.LoadingStatus.Faild);
    }
    }, 10000);
    ok,这下所有的View都能添加加载状态的View显示效果了。






  • 相关阅读:
    创建基于MailKit和MimeKit的.NET基础邮件服务
    MailKit---获取邮件
    C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
    .net 开源 FTP 组件 edtFTPnet
    Consul1-window安装consul
    通信传输利器Netty(Net is DotNetty)介绍
    工作中,如何衡量一个人的 JavaScript 编码水平?
    10个有趣又能编译为JavaScript的语言,你用过哪些?
    一定要你明白Java中的volatile
    面试总被问到HTTP缓存机制及原理?看完你就彻底明白了
  • 原文地址:https://www.cnblogs.com/linux007/p/5809691.html
Copyright © 2011-2022 走看看