【React Native】渐变骨架屏组件SkeletonElement

React Native 渐变骨架屏组件 SkeletonElement 使用指南

一、前言

在移动端开发中,数据加载过程中的空白等待会显著降低用户体验。骨架屏(Skeleton Screen) 是一种广受推崇的加载策略:它通过渲染与真实内容结构一致的灰色占位块,在数据返回前给予用户明确的视觉反馈。

本文提供一个轻量、高性能、支持自定义样式的 SkeletonElement 组件,适用于任何需要占位展示的 UI 元素。


二、组件特性

  • 完全自定义样式 :通过 style 属性控制尺寸、方向、间距等
  • 流畅渐变动画 :使用 Animated 实现原生驱动的高帧率闪烁效果
  • 轻量无依赖:仅基于 React Native 内置模块,零第三方依赖
  • 灵活配色:支持自定义背景色和高亮色
  • 自动清理:组件卸载时自动停止动画,防止内存泄漏

三、快速上手

tsx 复制代码
<View>
  {/* 标题骨架 */}
  <SkeletonElement style={{ height: 24, width: '80%', marginBottom: 16 }} />
  
  {/* 多行文本骨架 */}
  <SkeletonElement style={{ height: 16, width: '100%', marginBottom: 8 }} />
  <SkeletonElement style={{ height: 16, width: '90%', marginBottom: 8 }} />
  <SkeletonElement style={{ height: 16, width: '95%' }} />
  
  {/* 按钮骨架 */}
  <SkeletonElement 
    style={{ 
      height: 48, 
      width: '50%', 
      borderRadius: 24, 
      alignSelf: 'center',
      marginTop: 20 
    }} 
  />
</View>

四、API 说明

Props

属性 类型 默认值 说明
style StyleProp<ViewStyle> undefined 自定义骨架样式(宽高、方向、圆角等)
backgroundColor string #E4E4E4 骨架背景色
highlightColor string #D0D0D0 高亮闪烁色(较背景色稍亮)
speed number 1600 完整闪烁周期(毫秒),值越小动画越快

五、源码解析

核心逻辑

  1. 动画驱动 :使用 useRef(new Animated.Value(0.4)) 创建不触发重渲染的动画值
  2. 循环闪烁 :通过 Animated.loop + Animated.sequence 实现"暗→亮→暗"的循环
  3. 性能优化 :启用 useNativeDriver: true,动画在原生线程运行
  4. 资源清理useEffect 返回清理函数,确保组件卸载时停止动画

关键代码片段

ts 复制代码
const opacityValue = useRef(new Animated.Value(0.4)).current;

useEffect(() => {
  Animated.loop(
    Animated.sequence([
      Animated.timing(opacityValue, { toValue: 1, ... }),
      Animated.timing(opacityValue, { toValue: 0.4, ... })
    ])
  ).start();

  return () => opacityValue.stopAnimation();
}, [opacityValue, speed]);

六、完整源码

tsx 复制代码
import React, {useEffect, useRef} from 'react';
import {Animated, Easing, StyleProp, View, ViewStyle} from 'react-native';

interface SkeletonElementProps {
  style?: StyleProp<ViewStyle>;
  backgroundColor?: string;
  highlightColor?: string;
  speed?: number;
}

export const SkeletonElement: React.FC<SkeletonElementProps> = ({
  style,
  backgroundColor = '#E4E4E4',
  highlightColor = '#D0D0D0',
  speed = 1600,
}) => {
  const useSkeletonAnimation = (speed: number) => {
    const opacityValue = useRef(new Animated.Value(0.4)).current;

    useEffect(() => {
      Animated.loop(
        Animated.sequence([
          Animated.timing(opacityValue, {
            toValue: 1,
            duration: speed / 2,
            easing: Easing.inOut(Easing.ease),
            useNativeDriver: true,
          }),
          Animated.timing(opacityValue, {
            toValue: 0.4,
            duration: speed / 2,
            easing: Easing.inOut(Easing.ease),
            useNativeDriver: true,
          }),
        ]),
      ).start();

      // 返回清理函数
      return () => {
        opacityValue.stopAnimation();
      };
    }, [opacityValue, speed]);

    return opacityValue;
  };

  const opacityValue = useSkeletonAnimation(speed);

  // 合并样式
  const skeletonStyle: ViewStyle = {
    backgroundColor,
    overflow: 'hidden',
    position: 'relative',
    ...(style as ViewStyle),
  };

  // 添加渐变动画效果
  const highlightOverlay = (
    <Animated.View
      style={{
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: highlightColor,
        opacity: opacityValue,
      }}
    />
  );

  return <View style={skeletonStyle}>{highlightOverlay}</View>;
};

💡 提示:将此组件与条件渲染结合,即可实现优雅的数据加载过渡:

tsx 复制代码
{loading ? <SkeletonElement style={{ height: 200 }} /> : <RealContent />}

相关推荐
哈哈你是真的厉害4 小时前
小白基础入门 React Native 鸿蒙跨平台开发:实现一个简单的个人所得税计算器
react native·react.js·harmonyos
哈哈你是真的厉害5 小时前
小白基础入门 React Native 鸿蒙跨平台开发:二维码生成工具(通过生成网址生成)
react native·react.js·harmonyos
摘星编程9 小时前
OpenHarmony环境下React Native:Sensors摇一摇换图
javascript·react native·react.js
摘星编程10 小时前
React Native鸿蒙版:Bluetooth扫描蓝牙设备
react native·react.js·harmonyos
哈哈你是真的厉害11 小时前
小白基础入门 React Native 鸿蒙跨平台开发:模拟一个URL解析工具
react native·react.js·harmonyos
哈哈你是真的厉害12 小时前
小白基础入门 React Native 鸿蒙跨平台开发:实现一个简单的记账本小工具
react native·react.js·harmonyos
摘星编程12 小时前
在OpenHarmony上用React Native:MapView路线规划
javascript·react native·react.js
摘星编程1 天前
用React Native开发OpenHarmony应用:timing定时动画参数
javascript·react native·react.js
哈哈你是真的厉害1 天前
基础入门 React Native 鸿蒙跨平台开发:多种Switch 开关介绍
react native·react.js·harmonyos
摘星编程1 天前
在OpenHarmony上用React Native实现AnimatedValue补间动画
javascript·react native·react.js