HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新

发布于 1周前 作者 vueper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next–自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新

0、自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新

1、代码
```javascript
import { PullToRefresh } from '[@ohos](/user/ohos)/pulltorefresh';
import { R } from '[@ohos](/user/ohos)/res';
import { Constants } from '../../constants/Constants';
import { StyleConstants } from '../../constants/StyleConstants';
import { LoadingStatus } from '../../viewmodel/CommonEnums';
import { toast } from '../../utils/ToastUtils';
import { Logger } from '../../utils/Logger';

[@Component](/user/Component)
export struct ListStatusView {
  [@Link](/user/Link) [@Watch](/user/Watch)("listDataChange") listData: object[];
  [@Link](/user/Link) loadingStatus: LoadingStatus;
  [@BuilderParam](/user/BuilderParam) customSkeletonView: () => void = this.baseSkeletonView;
  [@BuilderParam](/user/BuilderParam) customFailureView: () => void = this.baseFailureView;
  [@BuilderParam](/user/BuilderParam) customEmptyView: () => void = this.baseEmptyView;
  [@BuilderParam](/user/BuilderParam) listView: () => void;
  listScroller: Scroller = new Scroller();
  [@State](/user/State) currentPage: number = 1;
  getList?: (page: number) => void;
  [@State](/user/State) columnOpacity: number = 1;
  resolve: ((value: string | PromiseLike<string>) => void) | undefined = undefined;

  aboutToAppear(): void {
    if (this.getList) {
      this.currentPage = 1
      this.getList(this.currentPage)
    }
  }

  listDataChange() {
    setTimeout(() => {
      if (this.resolve) {
        this.resolve(this.currentPage === 1 ? '刷新完成了' : '')
      }
    }, 100)
  }

  startAnimation(): void {
    animateTo(Constants.SKELETON_ANIMATION, () => {
      this.columnOpacity = 0.5;
    });
  }

  [@Builder](/user/Builder)
  baseSkeletonView() {
    Column() {
      Text("AI-ERP")
        .fontColor(R.color.color_ECECEC)
        .fontSize(R.float.vp40)
        .fontWeight(FontWeight.Bold)
    }
    .opacity(this.columnOpacity)
    .onAppear(() => {
      this.startAnimation();
    })
  }

  [@Builder](/user/Builder)
  baseFailureView() {
    Row() {
      Column() {
        Image($r('app.media.ic_failure'))
          .width(R.float.vp120)
          .height(R.float.vp120)
        Text(R.string.str_load_failed)
          .fontColor(R.color.color_reload_title_color)
          .fontFamily(StyleConstants.HARMONY_HEI_TI_FONT_FAMILY)
          .fontSize(R.float.fp14)
          .margin({ top: R.float.vp8 })

        Button(R.string.str_reload)
          .height(R.float.vp32)
          .fontColor(R.color.color_main_red_color)
          .fontFamily(StyleConstants.HARMONY_HEI_TI_FONT_FAMILY)
          .fontSize(R.float.fp12)
          .backgroundColor(Color.Transparent)
          .margin({ top: R.float.vp8 })
          .borderWidth(1)
          .borderColor(R.color.color_main_red_color)
          .borderRadius(R.float.vp16)
          .onClick(() => {
            if (this.getList) {
              this.currentPage = 1;
              this.getList(this.currentPage)
            }
          })

      }
    }
    .justifyContent(FlexAlign.Center)
  }

  [@Builder](/user/Builder)
  baseEmptyView() {
    List({ space: 0, scroller: this.listScroller }) {
      ListItem() {
        Column() {
          Image(R.media.ic_empty)
            .size({ width: R.float.vp120, height: R.float.vp120 })
          Text(R.string.str_empty_data)
            .fontColor("#DCDBDB")
            .fontSize(R.float.fp18)
            .margin({
              top: 10
            })
        }
        .justifyContent(FlexAlign.Center)
      }
      .width(Constants.FULL_PARENT)
      .height(Constants.FULL_PARENT)
    }
    .scrollBar(BarState.Off)
    .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
    .backgroundColor(R.color.colorPageBG)
    .width(Constants.FULL_PARENT)
    .layoutWeight(1)
  }

  build() {
    Stack() {
      if (this.loadingStatus === LoadingStatus.LOADING) {
        this.customSkeletonView() // 骨架屏
      }
      if (this.loadingStatus === LoadingStatus.FAILED) {
        this.customFailureView() // 错误屏
      }
      if (this.loadingStatus === LoadingStatus.SUCCESS || this.loadingStatus === LoadingStatus.NO_MORE) { // 加载完成或者是最后一页
        PullToRefresh({
          data: this.listData,
          scroller: this.listScroller,
          customList: () => {
            if (this.listData.length === 0) {
              this.customEmptyView()  //
            } else {
              this.listView()
            }
          },
          onRefresh: () => {
            return new Promise<void>((resolve, reject) => {
              this.currentPage = 1;
              if (this.getList) {
                this.getList(this.currentPage)
              }
              this.resolve = resolve
            });
          },
          onLoadMore: () => {
            return new Promise<void>((resolve, reject) => {
              if (this.loadingStatus === LoadingStatus.NO_MORE) {
                setTimeout(() => {
                  toast("没有更多数据了")
                  resolve('')
                }, 500)
                return
              }
              this.currentPage += 1;
              if (this.getList) {
                this.getList(this.currentPage)
              }
              this.resolve = resolve
            });
          },
          customLoad: null,
          customRefresh: null,
        })
          .width(StyleConstants.FULL_PERCENT)
          .layoutWeight(1)

      }
    }
    .layoutWeight(1)
  }
}

1、调用

ListStatusView({
  loadingStatus: this.loadingStatus,
  listData: this.listData,
  getList: (page): void => {
    // 请求列表数据
    this.workModel.getCCList(page)
      .then((res: ApplyListBean[]) => {
        this.listData = res
        this.loadingStatus = this.workModel.loadingStatus
      })
  },
  listView: () => {
    this.listViewBuilder();
  },
  listScroller: this.scroller
})

更多关于HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对帖子标题“HarmonyOS 鸿蒙Next–自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新”的问题,以下回答专注于鸿蒙系统相关的技术实现,不涉及Java或C语言内容:

在HarmonyOS中自定义一个包含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载和上拉刷新功能的ListStatusView,可以通过以下步骤实现:

  1. 定义自定义组件:首先,创建一个自定义组件类,继承自合适的容器组件,如DependentLayout

  2. 状态管理:在自定义组件内部,定义一个枚举或常量类来表示不同的状态(骨架屏、空数据、错误、正常)。

  3. 布局管理:根据当前状态,动态显示或隐藏相应的布局。例如,首次进入时显示骨架屏布局,数据为空时显示空数据布局,请求出错时显示错误布局。

  4. 事件监听:为下拉刷新和上拉加载功能添加事件监听器,当用户触发这些动作时,调用相应的方法来处理数据加载。

  5. 数据请求与更新:在数据请求成功后,更新组件状态并刷新数据列表;在请求失败时,显示错误布局并提供重新请求的接口。

  6. 动画效果:为骨架屏添加动画效果以提升用户体验。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部