HarmonyOS 鸿蒙Next中如何实现骨架屏(Skeleton Loading)?

HarmonyOS 鸿蒙Next中如何实现骨架屏(Skeleton Loading)? **问题描述:**数据加载时显示占位动画,提升体验。

3 回复

**详细回答:**用 @State loading 控制显示真实内容或骨架组件。

✅ 正确做法

/**
 * @author J.query
 * @date 2025/12/26 11:48
 * @email j-query@foxmail.com
 Description:
 */

@Component
struct SkeletonItem {
  build() {
    Row() {
      Blank().width(60).height(60).backgroundColor('#eee')
      Column({ space: 8 }) {
        Blank().width('80%').height(20).backgroundColor('#eee')
        Blank().width('60%').height(16).backgroundColor('#eee')
      }
      .layoutWeight(1)
    }
    .padding(12)
  }
}

@Entry
@Component
struct NewsPage {
  [@State](/user/State) loading: boolean = true;
  [@State](/user/State) news: string[] = [];

  aboutToAppear() {
    setTimeout(() => {
      this.news = ['新闻1', '新闻2'];
      this.loading = false;
    }, 1500);
  }

  build() {
    List() {
      if (this.loading) {
        ForEach([1, 2, 3, 4, 5], (item: number, index: number) => {
          ListItem() {
            SkeletonItem()
          }
        })
      } else {
        ForEach(this.news, (item: string, index: number) => {
          ListItem() {
            Text(item)
          }
        })
      }
    }
  }
}

⚠️ 避坑指南

骨架屏应轻量;避免复杂动画影响性能。

🎯 效果

cke_1331.png cke_2710.png

加载过程更流畅,减少用户焦虑。

更多关于HarmonyOS 鸿蒙Next中如何实现骨架屏(Skeleton Loading)?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可通过ArkUI的Skeleton组件实现骨架屏。该组件提供SkeletonView容器,用于包裹目标组件,并在数据加载前显示占位骨架。主要属性包括count(重复次数)、duration(动画时长)和borderRadius(圆角)。通过show属性控制骨架屏的显示与隐藏。

在HarmonyOS Next中,可以通过ArkUI的组件和动画能力高效实现骨架屏效果。核心是利用FlexColumnRow等容器组件结合Blank组件或自定义Component来模拟内容布局,并通过属性动画控制背景色的明暗变化。

常用实现方案如下:

  1. 使用Blank组件作为占位块Blank组件本身是空白占位,可以通过设置其backgroundColorwidthheightmargin等样式,精确模拟文本行、图片、卡片等元素的形状和间距。这是最轻量、最灵活的方式。

  2. 为占位块添加闪烁动画: 创建一个@State变量(如opacityValue)控制背景色的不透明度或颜色值。在aboutToAppear或数据加载开始时,使用animateTo或关键帧动画(KeyframeAnimation)循环改变该变量,实现明暗渐变效果。 示例代码片段(概念):

    @State opacityValue: number = 0.3;
    // 在加载状态中触发循环动画
    startSkeletonAnimation() {
      animateTo({
        duration: 1000,
        iterations: -1, // 无限循环
        animation: () => {
          this.opacityValue = (this.opacityValue === 0.3 ? 0.8 : 0.3);
        }
      });
    }
    

    Blank组件的背景色中应用该动态值,例如backgroundColor:rgba(240,240,240,${this.opacityValue})``。

  3. 封装为自定义组件: 将一组表示特定模块(如文章标题、头像+昵称、卡片)的Blank占位布局封装成自定义组件(@Component),并暴露参数(如行数、尺寸)以便复用。通过组件的visibility属性或条件渲染控制骨架屏与真实内容的切换。

  4. 布局结构与真实内容保持一致: 骨架屏的占位块组合结构应与即将加载的真实UI布局完全一致,确保切换时不会出现布局偏移。建议直接复制真实布局的容器结构,将其中的内容组件替换为动态样式的Blank占位块。

切换时机: 在数据加载的Promise的thencatch回调中,将控制骨架屏显示的@State变量(如isLoading)设置为false,并同时将真实数据绑定到对应组件。

此方案仅使用ArkUI原生能力,性能开销小,能有效提升加载过程的可视化体验。

回到顶部