Harmony OS :状态页管理

前言:

 在开发响应式鸿蒙应用时,我们实现了基于网络状态和数据的动态页面展示方案。虽然单个页面的修改可以在当前页面完成,但需要确保整个项目的所有界面都保持一致的响应逻辑和用户体验。接下来我们进行封装一个状态页。 

一、需求输入

我们按照以下的需求写一个鸿蒙的状态页: 
  状态分类:网络层异常,数据层异常,服务层异常
  交互设计规范:网络异常界面(提示暂无网络),空数据界面(提示暂无数据,请稍后再试),服务异常界面(服务器开小差)

二、技术 WrappedBuilder:

WrappedBuilder是鸿蒙ArkUI框架中用于封装全局@Builder函数的工具类,主要解决构建器动态调用的技术难题 

三、实现方案

1,使用PageStatus进行管理page状态

2,使用contentBuilder展示有数据界面

3,loadingStatusBuilder展示加载界面

4,noContentBuilder展示无数据界面

5,errorStatusBuilder展示错误数据界面

6,使用StatusManager进行管理界面

封装的组件:

@Component
export struct StatusComponent {
  @Prop pageHeight: Length = "100%" //page 高度
  @Prop pageWidth: Length = "100%" //page 宽度
  @Require @BuilderParam contentBuilder: () => void; //内容布局
  @Prop pageStatus: PageStatus = PageStatus.Undefined //page状态
  @BuilderParam loadingStatusBuilder: () => void //自定义loading Builder
  @BuilderParam noContentBuilder: () => void //自定义无内容Builder
  @BuilderParam errorStatusBuilder: () => void //自定义错误Builder
  outSideControlStatus: boolean = false
  errorEvent?: () => void //全局状态下的error Builder点击回调
 
  aboutToAppear() {
    //无网界面
    if (!this.outSideControlStatus && !CommonNetWorkUtils.isNetworkAvailable()) {
      this.pageStatus = PageStatus.NetError
    }
  }
 
  build() {
    Stack() {
      if (this.pageStatus == PageStatus.Loading) {
        if (this.loadingStatusBuilder) {
          this.loadingStatusBuilder()
        } else {
          StatusManager.getInstance().getLoadingWrapBuilder()?.builder()
        }
      } else if (this.pageStatus == PageStatus.NoContent) {
        if (this.noContentBuilder) {
          this.noContentBuilder()
        } else {
          StatusManager.getInstance().getNoContentWrapBuilder()?.builder()
        }
      } else if (this.pageStatus == PageStatus.NetError) {
        if (this.errorStatusBuilder) {
          this.errorStatusBuilder()
        } else {
          StatusManager.getInstance().getErrorWrapBuilder()?.builder(this.errorEvent)
        }
      } else {
        this.contentBuilder()
      }
    }
    .height(this.pageHeight)
    .width(this.pageWidth)
    .align(Alignment.TopStart)
  }
}

管理状态界面

export class StatusManager {
  private static mInstance: StatusManager
 
  private constructor() {
  }
 
  public static getInstance(): StatusManager {
    if (StatusManager.mInstance == null) {
      StatusManager.mInstance = new StatusManager()
    }
    return StatusManager.mInstance
  }
 
  private loadingWrapBuilder?: WrappedBuilder<[]>
  private noContentWrapBuilder?: WrappedBuilder<[]>
  private errorWrapBuilder?: WrappedBuilder<[() => void]>
 
  /**
   * 设置加载中包装构建器
   * @param loadingWrapBuilder 加载中包装构建器
   */
  public setLoadingWrapBuilder(loadingWrapBuilder: WrappedBuilder<[]>): StatusManager {
    this.loadingWrapBuilder = loadingWrapBuilder
    return this
  }
 
  /**
   * 设置无内容包装构建器
   * @param noContentWrapBuilder 无内容包装构建器
   */
  public setNoContentWrapBuilder(noContentWrapBuilder: WrappedBuilder<[]>): StatusManager {
    this.noContentWrapBuilder = noContentWrapBuilder
    return this
  }
 
  /**
   * 设置错误包装构建器
   * @param errorWrapBuilder 错误包装构建器
   */
  public setErrorWrapBuilder(errorWrapBuilder: WrappedBuilder<[() => void]>): StatusManager {
    this.errorWrapBuilder = errorWrapBuilder
    return this
  }
 
  /**
   * 获取加载中包装构建器
   */
  public getLoadingWrapBuilder(): WrappedBuilder<[]> | undefined {
    return this.loadingWrapBuilder;
  }
 
  /**
   * 获取无内容包装构建器
   */
  public getNoContentWrapBuilder(): WrappedBuilder<[]> | undefined {
    return this.noContentWrapBuilder;
  }
 
  /**
   * 获取错误包装构建器
   */
  public getErrorWrapBuilder(): WrappedBuilder<[() => void]> | undefined {
    return this.errorWrapBuilder;
  }
}

设置状态界面

StatusManager.getInstance() 
.setLoadingWrapBuilder(wrapBuilder(DefaultLoadingComponent)) 
.setNoContentWrapBuilder(wrapBuilder(DefaultEmptyComponent)) 
.setErrorWrapBuilder(wrapBuilder(DefaultNoNetComponent))

项目中使用状态界面组件:

StatusComponent({
  pageStatus: this.loadingState,
  pageWidth: FULL_WIDTH,
  pageHeight:FULL_HEIGHT,
  contentBuilder: () => {
    this.contentView()
  },
  noContentBuilder:()=>{
    this.emptyView()
  }
})

你可能感兴趣的:(harmonyos)