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

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

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


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


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

我们一般在写网络请求的时候,如果不涉及什么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();
}
目录
相关文章
|
存储 机器学习/深度学习 人工智能
AllData数据中台核心菜单十二:数据同步平台
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
AllData数据中台核心菜单十二:数据同步平台
|
12月前
|
XML 语音技术 Android开发
Android中TextToSpeech的使用
本文介绍了在Android开发中使用TextToSpeech(TTS)实现语音合成的功能。通过实例代码展示了TTS的初始化、语言设置、语音播放及队列模式的选择,并提供了将语音保存为音频文件的方法。项目中包含一个简单的按钮触发朗读功能,适合初学者学习和实践。代码示例完整,涵盖Activity生命周期管理与XML布局设计。
824 4
|
XML 前端开发 Android开发
Kotlin教程笔记(80) - MVVM架构设计
Kotlin教程笔记(80) - MVVM架构设计
|
弹性计算 固态存储 大数据
2024阿里云服务器租用价格表(一年/按月/按小时报价明细)
阿里云服务器2024年最新租用价格表显示,轻量应用服务器2核2G3M带宽一年82元(约6.8元/月),2核4G4M带宽轻量服务器一年298元。新老用户共享99元一年的2核2G3M带宽ECS经济型e实例服务器与199元一年的企业专享2核4G5M带宽ECS u1实例服务器优惠。4核16G10M带宽游戏服务器70元/月,8核32G10M带宽160元/月。GPU服务器如gn6v和gn6i等提供新用户专享折扣。续费折扣方面,续费一年享有7.5折,续费五年则有3折优惠。按小时计费的云服务器ECS实例中,如ecs.u1-c1m4.large(2核8G)每小时0.45元。
36223 17
|
芯片
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
2050 0
|
缓存 算法 C语言
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
416 0
|
移动开发 前端开发 数据管理
构建高效Android应用:采用MVVM架构与LiveData的全面指南
在移动开发领域,构建一个既快速又可靠的应用对于开发者来说至关重要。随着Android Jetpack组件的推出,MVVM(Model-View-ViewModel)架构和LiveData已成为实现响应式、可测试且易于维护应用的首选解决方案。本文将深入探讨如何在Android应用中实施MVVM模式,以及如何利用LiveData来优化UI组件的数据更新流程,确保用户界面与业务逻辑之间的高度解耦和流畅交互。
400 4
|
C++
SDL基础使用02(加载bmp图片、纹理和渲染)
这篇文章介绍了如何使用SDL库在C++中加载和显示BMP图片,以及如何使用纹理和渲染器进行更高级的图形处理。
342 2
|
存储 缓存 关系型数据库
深度解密 MySQL 的 Buffer Pool
深度解密 MySQL 的 Buffer Pool
393 1
|
算法 数据可视化 调度
基于PSO粒子群优化的车间调度问题求解matlab仿真,输出甘特图
基于PSO粒子群优化的MATLAB仿真解决车间调度问题,输入机器与工作完成时间,输出甘特图与收敛图,实现多机器多任务最优并行调度。使用MATLAB 2022a版本运行,通过模拟鸟群觅食行为,不断更新粒子速度与位置寻找最优解,采用工序编码,总加工时间为适应度函数,实现快速收敛并可视化调度结果。
620 16

热门文章

最新文章