一个简单的页面加载管理类(包含加载中,加载失败,数据为空,加载成功)(上)

简介: 在最近公布的比赛框架中,发现了页面加载管理类,觉得挺有用的,所以做个简单的笔记。

在最近公布的比赛框架中,发现了页面加载管理类,觉得挺有用的,所以做个简单的笔记。


什么是页面加载管理类呢?(大佬可直接跳过翻看实现过程)


如果能有这个问题,那么很好,哈哈哈,你和我一样,刚开始都挺疑惑的。

我们一般在写网络请求的时候,如果不涉及什么MVP,或者别的,就一个简单网络请求,然后再成功的结果里刷新View,请求过程中总不能白屏吧,所以有些人可能会让转一个圈,或者显示加载中的布局,然后等成功后再隐藏掉,显示具体的布局view。这样的话,也没什么问题,但是如果你的状态需要多个,这个时候就很烦了。总不能每个状态的判断一下吧。再者说这样也不利于你解耦。


出于上面的需求,我们用下面的demo,来解决问题,先用一张图来看效果吧。



我们来具体看一下实现过程

/**
 * 页面加载管理类,根据不同的状态显示不同的view
 */
public abstract class ContentPage extends FrameLayout{
  /**加载中的view*/
  private View loadingView;
  /**加载失败的view*/
  private View errorView;
  /**加载数据为空的view*/
  private View emptyView;
  /**加载成功的view*/
  private View successView;
  /**默认是加载中的状态*/
  private PageState mState = PageState.STATE_LOADING;
  /**
   * 定义页面状态常量
   *
   */
  public enum PageState{
    STATE_LOADING(0),/*加载中的状态*/
    STATE_SUCCESS(1),/*加载成功的状态*/
    STATE_ERROR(2),/*加载失败的状态*/
    STATE_EMPTY(3);/*加载数据为空的状态*/
    private int value;
    PageState(int value){
      this.value = value;
    }
    public int getValue(){
      return value;
    }
  }
  public ContentPage(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initPage();
  }
  public ContentPage(Context context, AttributeSet attrs) {
    super(context, attrs);
    initPage();
  }
  public ContentPage(Context context) {
    super(context);
    initPage();
  }
  /**
   * 初始化Page
   */
  private void initPage(){
    LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
    if(loadingView==null){/*天然往ContentPage中添加4个状态对应的view,然后根据不同状态,显示不同的view,添加LoadingView*/
      loadingView = View.inflate(getContext(), R.layout.page_loading, null);
    }
    addView(loadingView, params);
    if(errorView==null){/*添加ErrorView*/
      errorView = View.inflate(getContext(), R.layout.page_error, null);
      Button btn_reload = errorView.findViewById(R.id.btn_reload);
      btn_reload.setOnClickListener(v -> {
        mState = PageState.STATE_LOADING;
        showPage();
        loadDataAndRefreshPage();/*重新加载*/
      });
    }
    addView(errorView, params);
    if(emptyView==null){/*添加EmptyView*/
      emptyView = View.inflate(getContext(), R.layout.page_empty, null);
    }
    addView(emptyView, params);
    if(successView==null){/*添加SuccessView*/
      successView = createSuccessView();
    }
    if(successView==null){
      throw new IllegalArgumentException("The method createSuccessView() can not return null!");
    }else {
      addView(successView, params);
    }
    showPage();/*根据不同的state显示不同的view*/
    loadDataAndRefreshPage();/*请求数据然后刷新View*/
  }
  /**
   * 请求服务器的数据,然后根据加载的数据刷新View
   */
  private void loadDataAndRefreshPage(){
    new Thread(){
      public void run() {
        Object result = loadData();/*获取加载完成的数据*/
        mState = checkData(result);/*根据数据判断当前page的状态*/
        /*根据最新state,刷新View*/
        CommonUtil.runOnUIThread(() -> showPage());
      }
    }.start();
  }
  /**
   * 根据数据检查对应的状态
   * @return
   */
  private PageState checkData(Object result){
    if(result!=null){
      if(result instanceof List){
        List list = (List) result;
        if(list.size()==0){
          return PageState.STATE_EMPTY;/*加载数据为空*/
        }else {
          return PageState.STATE_SUCCESS;/*加载成功*/
        }
      }else {
        return PageState.STATE_SUCCESS;/*加载成功*/
      }
    }else {
      return PageState.STATE_ERROR;/*加载失败*/
    }
  }
  public void refreshPage(Object o) {
    if (o == null) {
      //说明木有数据,那么对应的state应该是error
      mState = PageState.STATE_ERROR;
    } else {
      //说明请求回来的有数据,那么对应的state应该是success
      mState = PageState.STATE_SUCCESS;
    }
    showPage();
  }
  /**
   * 根据不同的state显示不同的view
   */
  private void showPage(){
    loadingView.setVisibility(mState== PageState.STATE_LOADING?View.VISIBLE:View.INVISIBLE);
    errorView.setVisibility(mState== PageState.STATE_ERROR?View.VISIBLE:View.INVISIBLE);
    emptyView.setVisibility(mState== PageState.STATE_EMPTY?View.VISIBLE:View.INVISIBLE);
    successView.setVisibility(mState== PageState.STATE_SUCCESS?View.VISIBLE:View.INVISIBLE);
  }
  /**
   * 每个界面的成功view都不一样,应该由每个界面自己提供
   * @return
   */
  public abstract View createSuccessView();
  /**
   * 由于每个界面加载数据的过程不一样,我只需要关心它加载回来之后的数据,然后根据数据刷新View
   * @return
   */
  public abstract Object loadData();
}
目录
相关文章
|
1月前
|
JavaScript 前端开发 测试技术
如何判断网站加载速度是否得到优化?
如何判断网站加载速度是否得到优化?
|
2月前
|
缓存 前端开发 JavaScript
一些有效的方法来加快网站的加载速度
【10月更文挑战第8天】一些有效的方法来加快网站的加载速度
115 62
|
2月前
|
监控 开发者
确保动态导入模块按正确顺序加载
【10月更文挑战第12天】 在复杂应用开发中,确保动态导入模块按正确顺序加载至关重要,直接影响应用性能、功能和稳定性。本文深入探讨了动态模块加载顺序的影响因素、解决方案及实践案例,提供了详细的策略和方法,帮助开发者有效管理模块加载顺序,提升应用质量。
|
JavaScript 前端开发
react 实现图片正在加载中 加载完成 加载失败三个阶段的
最近博客写道项目列表中,发现这里比较多图片,一开加载会比较慢,然后就想要用一个loading的图片来占位。与此同时,如果图片加载失败那么显示错误的图片,不显示一个原有的错误,那样比较难看。
react 实现图片正在加载中 加载完成 加载失败三个阶段的
一个简单的页面加载管理类(包含加载中,加载失败,数据为空,加载成功)(下)
在最近公布的比赛框架中,发现了页面加载管理类,觉得挺有用的,所以做个简单的笔记。
125 0
一个简单的页面加载管理类(包含加载中,加载失败,数据为空,加载成功)(下)
|
前端开发
一个"剑气"加载🌪️
一个"剑气"加载🌪️
|
测试技术 编译器 C++
|
缓存 图形学