欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net

在这里插入图片描述

📋 前言

在现代移动应用开发中,用户体验至关重要。当应用需要加载网络数据时,直接显示空白页面会让用户感到困惑和焦虑。骨架屏(Skeleton Screen)作为一种优秀的加载占位方案,能够在数据加载完成前展示页面的大致结构,给用户一种"内容即将出现"的心理预期,大大提升了用户体验。react-native-shimmer-placeholder 是一个功能强大的骨架屏组件库,支持闪烁动画效果,可以轻松创建优雅的加载占位符。

🎯 库简介

基本信息

  • 库名称: react-native-shimmer-placeholder
  • 版本信息: 2.0.9 支持 RN 0.72/0.77 版本
  • 官方仓库: https://github.com/tomzaku/react-native-shimmer-placeholder
  • 主要功能:
    • ✨ 闪烁动画效果
    • 🎨 自定义占位符样式
    • 🌈 支持渐变颜色
    • 📱 跨平台支持(iOS、Android、HarmonyOS)
    • 🔄 动画控制(开始、停止、反向)
    • 🎯 与 Linear Gradient 集成

为什么需要骨架屏?

特性 传统加载方式 shimmer-placeholder
用户体验 ⚠️ 空白等待 ✅ 视觉反馈
心理预期 ❌ 不确定状态 ✅ 内容预览
视觉连贯性 ⚠️ 突然出现 ✅ 平滑过渡
自定义能力 ⚠️ 需自行实现 ✅ 丰富配置
动画效果 ❌ 无或简陋 ✅ 专业闪烁效果
HarmonyOS 支持 ❌ 无 ✅ 完善适配

核心功能

功能 说明 HarmonyOS 支持
createShimmerPlaceholder 创建闪烁占位组件
visible 控制内容显示
shimmerColors 自定义闪烁颜色
duration 动画持续时间
shimmerWidthPercent 闪烁宽度百分比
isReversed 反向动画
getAnimated 获取动画对象

兼容性验证

在以下环境验证通过:

  • RNOH: 0.72.27; SDK: HarmonyOS-Next-DB1 5.0.0.25; IDE: DevEco Studio 5.0.3.400SP7; ROM: 3.0.0.25
  • RNOH: 0.77.18; SDK: HarmonyOS 5.1.1 Release; IDE: DevEco Studio 5.1.1.830; ROM: NEXT 5.1.0.150

📦 安装步骤

1. 安装依赖

请到三方库的 Releases 发布地址查看配套的版本信息:

Version Support RN version
2.0.9 0.72/0.77
# 使用 npm
npm install react-native-shimmer-placeholder@2.0.9

# 或者使用 yarn
yarn add react-native-shimmer-placeholder@2.0.9

2. 安装依赖库

本库依赖 react-native-linear-gradient,需要先安装该依赖:

# 使用 npm
npm install @react-native-oh-tpl/react-native-linear-gradient@3.0.0-0.5.0

# 或者使用 yarn
yarn add @react-native-oh-tpl/react-native-linear-gradient@3.0.0-0.5.0

3. 验证安装

安装完成后,检查 package.json 文件:

{
  "dependencies": {
    "react-native-shimmer-placeholder": "^2.0.9",
    "@react-native-oh-tpl/react-native-linear-gradient": "^3.0.0-0.5.0"
  }
}

🔧 HarmonyOS 平台配置 ⭐

依赖库配置

本库 HarmonyOS 侧实现依赖 @react-native-oh-tpl/react-native-linear-gradient 的原生端代码,如已在 HarmonyOS 工程中引入过该库,则无需再次引入,可跳过本章节步骤。

没有引入的按照流程引入

1. 在工程根目录的 oh-package.json5 添加 overrides 字段

打开 harmony/oh-package.json5,添加以下配置:

{
  // ... 其他配置
  "overrides": {
    "@rnoh/react-native-openharmony": "0.72.90"
  }
}

2. 引入原生端代码

打开 harmony/entry/oh-package.json5,添加以下依赖:

"dependencies": {
  "@react-native-oh-tpl/react-native-linear-gradient": "file:../../node_modules/@react-native-oh-tpl/react-native-linear-gradient/harmony/linear_gradient.har"
}

点击右上角的 sync 按钮,或者在终端执行:

cd entry
ohpm install

3. 配置 CMakeLists

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-oh-tpl/react-native-linear-gradient/src/main/cpp" ./linear_gradient)
# RNOH_END: manual_package_linking_1

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)

target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_linear_gradient)
# RNOH_END: manual_package_linking_2

4. 引入 LinearGradientPackage

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "LinearGradientPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
        std::make_shared<RNOHGeneratedPackage>(ctx),
        std::make_shared<SamplePackage>(ctx),
        + std::make_shared<LinearGradientPackage>(ctx),
    };
}

5. 在 ArkTS 侧引入 LinearGradientPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

import { LinearGradientPackage } from '@react-native-oh-tpl/react-native-linear-gradient/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
    new SamplePackage(ctx),
    new LinearGradientPackage(ctx)
  ];
}

然后编译、运行即可。

📖 API 详解

createShimmerPlaceholder - 创建闪烁占位组件

创建一个带有闪烁动画效果的占位符组件,需要传入 LinearGradient 组件作为参数。

类型(LinearGradient: Component) => Component

参数说明

参数 类型 必填 说明
LinearGradient Component 线性渐变组件,来自 react-native-linear-gradient 或 expo-linear-gradient

返回值:ShimmerPlaceholder 组件

使用场景

  • 创建骨架屏组件
  • 图片加载占位
  • 列表项加载占位
  • 内容区域加载占位
import { createShimmerPlaceholder } from "react-native-shimmer-placeholder";
import LinearGradient from "@react-native-oh-tpl/react-native-linear-gradient";

const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient);

const App = () => {
  return (
    <View style={styles.container}>
      <ShimmerPlaceholder width={200} height={20} />
      <ShimmerPlaceholder width={150} height={150} shimmerStyle={{ borderRadius: 75 }} />
    </View>
  );
};

visible - 控制内容显示

控制是否显示真实的子组件内容。当设置为 true 时,显示子组件;当设置为 false 时,显示闪烁占位符。

类型boolean

默认值false

使用场景

  • 数据加载完成后显示内容
  • 图片加载完成后显示图片
  • 条件渲染场景
import React, { useState, useEffect } from "react";
import { View, Image, Text } from "react-native";
import { createShimmerPlaceholder } from "react-native-shimmer-placeholder";
import LinearGradient from "@react-native-oh-tpl/react-native-linear-gradient";

const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient);

const UserProfile = () => {
  const [visible, setVisible] = useState(false);
  const [userData, setUserData] = useState(null);

  useEffect(() => {
    fetchUserData().then((data) => {
      setUserData(data);
      setVisible(true);
    });
  }, []);

  return (
    <View style={styles.container}>
      <ShimmerPlaceholder
        width={80}
        height={80}
        shimmerStyle={{ borderRadius: 40 }}
        visible={visible}
      >
        <Image
          source={{ uri: userData?.avatar }}
          style={{ width: 80, height: 80, borderRadius: 40 }}
        />
      </ShimmerPlaceholder>
      
      <ShimmerPlaceholder width={150} height={20} visible={visible}>
        <Text style={styles.name}>{userData?.name}</Text>
      </ShimmerPlaceholder>
    </View>
  );
};

shimmerColors - 自定义闪烁颜色

设置闪烁动画的颜色数组,通常使用两个或三个颜色值来创建渐变效果。

类型string[]

默认值['#f0f0f0', '#e0e0e0', '#f0f0f0']

使用场景

  • 深色主题适配
  • 品牌色定制
  • 视觉效果优化
const LightThemePlaceholder = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      shimmerColors={['#f0f0f0', '#e0e0e0', '#f0f0f0']}
    />
  );
};

const DarkThemePlaceholder = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      shimmerColors={['#333333', '#444444', '#333333']}
    />
  );
};

const BrandColorPlaceholder = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      shimmerColors={['#E3F2FD', '#BBDEFB', '#E3F2FD']}
    />
  );
};

duration - 动画持续时间

设置闪烁动画完成一个完整循环所需的时间,单位为毫秒。

类型number

默认值1000

使用场景

  • 快速闪烁效果
  • 慢速优雅效果
  • 动画节奏控制
const FastShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      duration={500}
    />
  );
};

const SlowShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      duration={2000}
    />
  );
};

shimmerWidthPercent - 闪烁宽度百分比

设置闪烁高亮区域的宽度占组件宽度的百分比,值为 0 到 1 之间。

类型number

默认值1

使用场景

  • 局部高亮效果
  • 聚焦效果
  • 特殊视觉需求
const WideShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      shimmerWidthPercent={1}
    />
  );
};

const NarrowShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      shimmerWidthPercent={0.5}
    />
  );
};

isReversed - 反向动画

设置闪烁动画是否反向播放。

类型boolean

默认值false

使用场景

  • 特殊动画效果
  • 多组件协调动画
const NormalShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      isReversed={false}
    />
  );
};

const ReversedShimmer = () => {
  return (
    <ShimmerPlaceholder
      width={200}
      height={20}
      isReversed={true}
    />
  );
};

stopAutoRun - 停止自动运行

设置组件挂载时是否停止闪烁动画,需要手动调用方法启动。

类型boolean

默认值false

使用场景

  • 手动控制动画开始时机
  • 条件触发动画
  • 性能优化
import React, { useRef } from "react";
import { View, TouchableOpacity, Text } from "react-native";
import { createShimmerPlaceholder } from "react-native-shimmer-placeholder";
import LinearGradient from "@react-native-oh-tpl/react-native-linear-gradient";

const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient);

const ManualControlExample = () => {
  const shimmerRef = useRef(null);

  const startAnimation = () => {
    shimmerRef.current?.run();
  };

  const stopAnimation = () => {
    shimmerRef.current?.stop();
  };

  return (
    <View style={styles.container}>
      <ShimmerPlaceholder
        ref={shimmerRef}
        width={200}
        height={20}
        stopAutoRun={true}
      />
      <View style={styles.buttonContainer}>
        <TouchableOpacity onPress={startAnimation} style={styles.button}>
          <Text>开始动画</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={stopAnimation} style={styles.button}>
          <Text>停止动画</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

shimmerStyle - 闪烁效果样式

设置闪烁占位符的样式,可以设置圆角、边框等样式属性。

类型ViewStyle

使用场景

  • 圆形头像占位
  • 圆角卡片占位
  • 自定义形状
const CirclePlaceholder = () => {
  return (
    <ShimmerPlaceholder
      width={80}
      height={80}
      shimmerStyle={{ borderRadius: 40 }}
    />
  );
};

const RoundedCardPlaceholder = () => {
  return (
    <ShimmerPlaceholder
      width={300}
      height={200}
      shimmerStyle={{ borderRadius: 12 }}
    />
  );
};

getAnimated - 获取动画对象

获取占位符的 Animated 对象,可以用于更复杂的动画控制。

类型() => Animated.Value

使用场景

  • 自定义动画序列
  • 与其他动画同步
  • 高级动画控制
import React, { useRef, useEffect } from "react";
import { Animated } from "react-native";
import { createShimmerPlaceholder } from "react-native-shimmer-placeholder";
import LinearGradient from "@react-native-oh-tpl/react-native-linear-gradient";

const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient);

const AdvancedAnimationExample = () => {
  const shimmerRef = useRef(null);

  useEffect(() => {
    if (shimmerRef.current) {
      const animatedValue = shimmerRef.current.getAnimated();
      Animated.timing(animatedValue, {
        toValue: 1,
        duration: 2000,
        useNativeDriver: false,
      }).start();
    }
  }, []);

  return (
    <ShimmerPlaceholder
      ref={shimmerRef}
      width={200}
      height={20}
    />
  );
};

📋 完整示例

在这里插入图片描述

import React, { useState, useEffect, useRef } from "react";
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  Image,
  TouchableOpacity,
  RefreshControl,
  SafeAreaView,
  StatusBar,
} from "react-native";
import { createShimmerPlaceholder } from "react-native-shimmer-placeholder";
import LinearGradient from "@react-native-oh-tpl/react-native-linear-gradient";

const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient);

type User = {
  id: number;
  name: string;
  avatar: string;
  bio: string;
  followers: number;
  following: number;
};

type Post = {
  id: number;
  title: string;
  excerpt: string;
  image: string;
  author: string;
  date: string;
};

const App: React.FC = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [userData, setUserData] = useState<User | null>(null);
  const [posts, setPosts] = useState<Post[]>([]);
  const [refreshing, setRefreshing] = useState(false);

  useEffect(() => {
    loadData();
  }, []);

  const loadData = async () => {
    setIsLoading(true);
    
    await new Promise((resolve) => setTimeout(resolve, 1500));
    
    setUserData({
      id: 1,
      name: "张三",
      avatar: "https://i.pravatar.cc/150?img=3",
      bio: "前端开发工程师 | 开源爱好者",
      followers: 1234,
      following: 567,
    });

    await new Promise((resolve) => setTimeout(resolve, 500));

    setPosts([
      {
        id: 1,
        title: "React Native 鸿蒙适配指南",
        excerpt: "本文详细介绍如何将 React Native 应用适配到鸿蒙系统...",
        image: "https://picsum.photos/400/200?random=1",
        author: "张三",
        date: "2024-01-15",
      },
      {
        id: 2,
        title: "性能优化最佳实践",
        excerpt: "探索 React Native 应用的性能优化技巧和最佳实践...",
        image: "https://picsum.photos/400/200?random=2",
        author: "李四",
        date: "2024-01-14",
      },
      {
        id: 3,
        title: "动画效果实现详解",
        excerpt: "学习如何在 React Native 中实现流畅的动画效果...",
        image: "https://picsum.photos/400/200?random=3",
        author: "王五",
        date: "2024-01-13",
      },
    ]);

    setIsLoading(false);
  };

  const onRefresh = async () => {
    setRefreshing(true);
    await loadData();
    setRefreshing(false);
  };

  const renderUserSkeleton = () => (
    <View style={styles.userSection}>
      <View style={styles.userHeader}>
        <ShimmerPlaceholder
          width={80}
          height={80}
          shimmerStyle={{ borderRadius: 40 }}
          shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
        />
        <View style={styles.userInfo}>
          <ShimmerPlaceholder
            width={120}
            height={24}
            style={{ marginBottom: 8 }}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
          <ShimmerPlaceholder
            width={200}
            height={16}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
        </View>
      </View>
      <View style={styles.userStats}>
        <View style={styles.statItem}>
          <ShimmerPlaceholder
            width={60}
            height={20}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
          <ShimmerPlaceholder
            width={40}
            height={14}
            style={{ marginTop: 4 }}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
        </View>
        <View style={styles.statItem}>
          <ShimmerPlaceholder
            width={60}
            height={20}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
          <ShimmerPlaceholder
            width={40}
            height={14}
            style={{ marginTop: 4 }}
            shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
          />
        </View>
      </View>
    </View>
  );

  const renderPostSkeleton = () => (
    <View style={styles.postCard}>
      <ShimmerPlaceholder
        width="100%"
        height={150}
        shimmerStyle={{ borderRadius: 8 }}
        shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
      />
      <View style={styles.postContent}>
        <ShimmerPlaceholder
          width="80%"
          height={20}
          style={{ marginBottom: 8 }}
          shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
        />
        <ShimmerPlaceholder
          width="100%"
          height={14}
          style={{ marginBottom: 4 }}
          shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
        />
        <ShimmerPlaceholder
          width="60%"
          height={14}
          shimmerColors={["#E8E8E8", "#F5F5F5", "#E8E8E8"]}
        />
      </View>
    </View>
  );

  const renderUser = () => (
    <View style={styles.userSection}>
      <View style={styles.userHeader}>
        <Image
          source={{ uri: userData?.avatar }}
          style={styles.avatar}
        />
        <View style={styles.userInfo}>
          <Text style={styles.userName}>{userData?.name}</Text>
          <Text style={styles.userBio}>{userData?.bio}</Text>
        </View>
      </View>
      <View style={styles.userStats}>
        <View style={styles.statItem}>
          <Text style={styles.statNumber}>{userData?.followers}</Text>
          <Text style={styles.statLabel}>关注者</Text>
        </View>
        <View style={styles.statItem}>
          <Text style={styles.statNumber}>{userData?.following}</Text>
          <Text style={styles.statLabel}>正在关注</Text>
        </View>
      </View>
    </View>
  );

  const renderPost = (post: Post) => (
    <View key={post.id} style={styles.postCard}>
      <Image source={{ uri: post.image }} style={styles.postImage} />
      <View style={styles.postContent}>
        <Text style={styles.postTitle}>{post.title}</Text>
        <Text style={styles.postExcerpt} numberOfLines={2}>
          {post.excerpt}
        </Text>
        <View style={styles.postMeta}>
          <Text style={styles.postAuthor}>{post.author}</Text>
          <Text style={styles.postDate}>{post.date}</Text>
        </View>
      </View>
    </View>
  );

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar barStyle="dark-content" backgroundColor="#FFFFFF" />
      <View style={styles.header}>
        <Text style={styles.headerTitle}>骨架屏示例</Text>
      </View>
      <ScrollView
        style={styles.scrollView}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }
      >
        {isLoading ? renderUserSkeleton() : renderUser()}

        <View style={styles.sectionHeader}>
          <Text style={styles.sectionTitle}>最新文章</Text>
        </View>

        {isLoading
          ? [1, 2, 3].map((i) => (
              <View key={i}>{renderPostSkeleton()}</View>
            ))
          : posts.map((post) => renderPost(post))}
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#FFFFFF",
  },
  header: {
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: "#E5E5EA",
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: "600",
    color: "#333333",
  },
  scrollView: {
    flex: 1,
  },
  userSection: {
    padding: 16,
    borderBottomWidth: 8,
    borderBottomColor: "#F5F5F5",
  },
  userHeader: {
    flexDirection: "row",
    alignItems: "center",
  },
  avatar: {
    width: 80,
    height: 80,
    borderRadius: 40,
  },
  userInfo: {
    marginLeft: 16,
    flex: 1,
  },
  userName: {
    fontSize: 20,
    fontWeight: "600",
    color: "#333333",
    marginBottom: 4,
  },
  userBio: {
    fontSize: 14,
    color: "#666666",
  },
  userStats: {
    flexDirection: "row",
    marginTop: 20,
    justifyContent: "center",
  },
  statItem: {
    alignItems: "center",
    marginHorizontal: 24,
  },
  statNumber: {
    fontSize: 18,
    fontWeight: "600",
    color: "#333333",
  },
  statLabel: {
    fontSize: 12,
    color: "#999999",
    marginTop: 4,
  },
  sectionHeader: {
    padding: 16,
    paddingBottom: 8,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: "600",
    color: "#333333",
  },
  postCard: {
    margin: 16,
    marginTop: 8,
    backgroundColor: "#FFFFFF",
    borderRadius: 12,
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
    overflow: "hidden",
  },
  postImage: {
    width: "100%",
    height: 150,
  },
  postContent: {
    padding: 12,
  },
  postTitle: {
    fontSize: 16,
    fontWeight: "600",
    color: "#333333",
    marginBottom: 8,
  },
  postExcerpt: {
    fontSize: 14,
    color: "#666666",
    lineHeight: 20,
    marginBottom: 8,
  },
  postMeta: {
    flexDirection: "row",
    justifyContent: "space-between",
  },
  postAuthor: {
    fontSize: 12,
    color: "#007AFF",
  },
  postDate: {
    fontSize: 12,
    color: "#999999",
  },
});

export default App;

⚠️ 注意事项

依赖库配置

本库依赖 react-native-linear-gradient,必须先正确配置该依赖库:

npm install @react-native-oh-tpl/react-native-linear-gradient@3.0.0-0.4.5

性能优化

在列表中使用骨架屏时,注意以下优化建议:

// ✅ 推荐:使用固定尺寸
<ShimmerPlaceholder width={200} height={20} />

// ❌ 不推荐:使用百分比可能导致布局抖动
<ShimmerPlaceholder width="80%" height={20} />

动画控制

对于复杂场景,可以使用 stopAutoRun 手动控制动画:

const shimmerRef = useRef(null);

// 手动启动动画
shimmerRef.current?.run();

// 手动停止动画
shimmerRef.current?.stop();

颜色配置

根据应用主题选择合适的骨架屏颜色:

// 浅色主题
const lightColors = ['#f0f0f0', '#e0e0e0', '#f0f0f0'];

// 深色主题
const darkColors = ['#333333', '#444444', '#333333'];

// 品牌色
const brandColors = ['#E3F2FD', '#BBDEFB', '#E3F2FD'];

常见问题

Q: 骨架屏不显示闪烁效果?

A: 检查是否正确安装并配置了 react-native-linear-gradient 依赖库。

Q: 动画卡顿或不流畅?

A: 确保没有在动画执行期间进行大量计算或渲染操作,可以尝试调整 duration 参数。

Q: 圆角不生效?

A: 使用 shimmerStyle 属性设置圆角,而不是 style 属性。

Q: 如何实现多行骨架屏?

A: 创建多个 ShimmerPlaceholder 组件并排列:

<View>
  <ShimmerPlaceholder width={200} height={16} style={{ marginBottom: 8 }} />
  <ShimmerPlaceholder width={180} height={16} style={{ marginBottom: 8 }} />
  <ShimmerPlaceholder width={150} height={16} />
</View>

📚 参考资料

  • 官方文档: https://github.com/tomzaku/react-native-shimmer-placeholder
  • 依赖库文档: https://github.com/react-native-oh-library/react-native-linear-gradient
  • 问题反馈: https://github.com/tomzaku/react-native-shimmer-placeholder/issues
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐