ProComponents, templates & AI tooling
2.3k

SkeletonGroup 骨架屏组

协调多个骨架屏占位,并提供统一的动画与加载态控制。

导入

import { SkeletonGroup } from 'heroui-native';

结构

<SkeletonGroup>
  <SkeletonGroup.Item />
</SkeletonGroup>
  • SkeletonGroup:根容器,为所有骨架项提供统一控制
  • SkeletonGroup.Item:单个骨架项,继承父级组的属性

用法

基础用法

SkeletonGroup 用共享的加载态与动画管理多个骨架项。

<SkeletonGroup isLoading={isLoading}>
  <SkeletonGroup.Item className="h-4 w-full rounded-md" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
  <SkeletonGroup.Item className="h-4 w-1/2 rounded-md" />
</SkeletonGroup>

容器布局

在组上使用 className 控制骨架项布局。

<SkeletonGroup isLoading={isLoading} className="flex-row items-center gap-3">
  <SkeletonGroup.Item className="h-12 w-12 rounded-lg" />
  <View className="flex-1 gap-1.5">
    <SkeletonGroup.Item className="h-4 w-full rounded-md" />
    <SkeletonGroup.Item className="h-3 w-2/3 rounded-md" />
  </View>
</SkeletonGroup>

isSkeletonOnly(纯骨架布局)

当组内仅有骨架与布局用 View(加载完成后无真实内容)时,使用 isSkeletonOnlyisLoadingfalse 时整个组会隐藏,避免空容器影响布局。

<SkeletonGroup
  isLoading={isLoading}
  isSkeletonOnly // isLoading 为 false 时隐藏整组
  className="flex-row items-center gap-3"
>
  <SkeletonGroup.Item className="h-12 w-12 rounded-lg" />
  {/* 该 View 仅用于布局,无加载后内容 */}
  <View className="flex-1 gap-1.5">
    <SkeletonGroup.Item className="h-4 w-full rounded-md" />
    <SkeletonGroup.Item className="h-3 w-2/3 rounded-md" />
  </View>
</SkeletonGroup>

动画变体

为组内所有项统一设置动画变体。

<SkeletonGroup isLoading={isLoading} variant="pulse">
  <SkeletonGroup.Item className="h-10 w-10 rounded-full" />
  <SkeletonGroup.Item className="h-4 w-32 rounded-md" />
  <SkeletonGroup.Item className="h-3 w-24 rounded-md" />
</SkeletonGroup>

自定义动画配置

为整组配置 shimmer 或 pulse。

<SkeletonGroup
  isLoading={isLoading}
  variant="shimmer"
  animation={{
    shimmer: {
      duration: 2000,
      highlightColor: 'rgba(59, 130, 246, 0.3)',
    },
  }}
>
  <SkeletonGroup.Item className="h-16 w-full rounded-lg" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
</SkeletonGroup>

进出场动画

组出现或消失时应用 Reanimated 过渡。

<SkeletonGroup
  entering={FadeInLeft}
  exiting={FadeOutRight}
  isLoading={isLoading}
  className="w-full gap-2"
>
  <SkeletonGroup.Item className="h-4 w-full rounded-md" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
</SkeletonGroup>

示例

import { Card, SkeletonGroup, Avatar } from 'heroui-native';
import { useState } from 'react';
import { Text, View, Image } from 'react-native';

export default function SkeletonGroupExample() {
  const [isLoading, setIsLoading] = useState(true);

  return (
    <SkeletonGroup isLoading={isLoading}>
      <Card className="p-4">
        <Card.Header>
          <View className="flex-row items-center gap-3 mb-4">
            <SkeletonGroup.Item className="h-10 w-10 rounded-full">
              <Avatar size="sm" alt="Avatar">
                <Avatar.Image
                  source={{ uri: 'https://i.pravatar.cc/150?img=4' }}
                />
                <Avatar.Fallback />
              </Avatar>
            </SkeletonGroup.Item>

            <View className="flex-1 gap-1">
              <SkeletonGroup.Item className="h-3 w-32 rounded-md">
                <Text className="font-semibold text-foreground">John Doe</Text>
              </SkeletonGroup.Item>
              <SkeletonGroup.Item className="h-3 w-24 rounded-md">
                <Text className="text-sm text-muted">@johndoe</Text>
              </SkeletonGroup.Item>
            </View>
          </View>

          <View className="mb-4 gap-1.5">
            <SkeletonGroup.Item className="h-4 w-full rounded-md">
              <Text className="text-base text-foreground">
                This is the first line of the post content.
              </Text>
            </SkeletonGroup.Item>
            <SkeletonGroup.Item className="h-4 w-full rounded-md">
              <Text className="text-base text-foreground">
                Second line with more interesting content to read.
              </Text>
            </SkeletonGroup.Item>
            <SkeletonGroup.Item className="h-4 w-2/3 rounded-md">
              <Text className="text-base text-foreground">
                Last line is shorter.
              </Text>
            </SkeletonGroup.Item>
          </View>
        </Card.Header>

        <SkeletonGroup.Item className="h-48 w-full rounded-lg">
          <View className="h-48 bg-surface-tertiary rounded-lg overflow-hidden">
            <Image
              source={{
                uri: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/backgrounds/cards/car1.jpg',
              }}
              className="h-full w-full"
            />
          </View>
        </SkeletonGroup.Item>
      </Card>
    </SkeletonGroup>
  );
}

更多示例见 GitHub 仓库

API 参考

SkeletonGroup

proptypedefaultdescription
childrenReact.ReactNode-SkeletonGroup.Item 与布局元素
isLoadingbooleantrue骨架项是否处于加载中
isSkeletonOnlybooleanfalsetrue 时,isLoadingfalse 隐藏整组(纯骨架布局)
variant'shimmer' | 'pulse' | 'none''shimmer'组内所有项的动画变体
animationSkeletonRootAnimation-动画配置
classNamestring-组容器额外 class
styleStyleProp<ViewStyle>-组容器自定义样式
...Animated.ViewPropsAnimatedProps<ViewProps>-支持 Reanimated Animated.View 全部属性

SkeletonRootAnimation

SkeletonGroup 动画配置,可为:

  • false"disabled":仅关闭根动画
  • "disable-all":关闭所有动画(含子级)
  • trueundefined:使用默认动画
  • object:自定义动画配置
proptypedefaultdescription
state'disabled' | 'disable-all' | boolean-关闭动画的同时仍允许自定义属性
entering.valueEntryOrExitLayoutTypeFadeIn自定义进入动画
exiting.valueEntryOrExitLayoutTypeFadeOut自定义退出动画
shimmer.durationnumber1500动画时长(毫秒)
shimmer.speednumber1速度倍率
shimmer.highlightColorstring-微光高光色
shimmer.easingEasingFunctionEasing.linear缓动函数
pulse.durationnumber1000动画时长(毫秒)
pulse.minOpacitynumber0.5最小不透明度
pulse.maxOpacitynumber1最大不透明度
pulse.easingEasingFunctionEasing.inOut(Easing.ease)缓动函数

SkeletonGroup.Item

proptypedefaultdescription
childrenReact.ReactNode-非加载态显示的内容
isLoadingboolean继承组是否加载中(覆盖组设置)
variant'shimmer' | 'pulse' | 'none'继承组动画变体(覆盖组设置)
animationSkeletonRootAnimation继承组动画配置(覆盖组设置)
classNamestring-单项额外 class
...Animated.ViewPropsAnimatedProps<ViewProps>-支持 Reanimated Animated.View 全部属性

特别说明

属性继承

SkeletonGroup.Item 从父级 SkeletonGroup 继承所有与动画相关的属性:

  • isLoading
  • variant
  • animation

单项可通过自身属性覆盖继承值。

本页目录