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

项目基于 RN 0.72.90 开发

📋 前言

,阴影效果是提升UI层次感和视觉体验的重要手段。react-native-shadow-2 是一个功能强大的阴影效果库,提供了跨平台一致的阴影渲染能力,支持渐变色阴影、自定义形状、多方向阴影等高级特性,是实现精美UI的理想选择。

🎯 库简介

基本信息

  • 库名称: react-native-shadow-2
  • 版本信息: 7.0.8 支持 RN 0.72 版本,7.1.1 支持 RN 0.77 版本
  • 官方仓库: https://github.com/SrBrahma/react-native-shadow-2
  • 鸿蒙仓库: https://github.com/ftzi/react-native-shadow-2
  • 主要功能:
    • 🎨 渐变色阴影效果
    • 📐 自定义阴影形状
    • 🔲 多方向阴影控制
    • 🎯 精确的阴影定位
    • ⚡ 高性能渲染
    • 📱 跨平台支持(iOS、Android、HarmonyOS)

为什么需要阴影库?

特性 原生方案 react-native-shadow-2
跨平台一致性 ⚠️ 差异大 ✅ 统一效果
渐变阴影 ❌ 不支持 ✅ 完美支持
自定义形状 ⚠️ 复杂 ✅ 简单配置
性能优化 ⚠️ 需手动优化 ✅ 自动优化
圆角阴影 ⚠️ 需额外处理 ✅ 原生支持
HarmonyOS 支持 ⚠️ 需适配 ✅ 完善适配

核心功能

功能 说明 HarmonyOS 支持
startColor 阴影起始颜色
endColor 阴影结束颜色
distance 阴影延伸距离
offset 阴影偏移
paintInside 内部绘制
sides 边控制
corners 角控制
style 子组件容器样式
stretch 水平拉伸
disabled 禁用阴影

兼容性验证

在以下环境验证通过:

  • RNOH: 0.72.90; SDK: HarmonyOS 6.0.0; IDE: DevEco Studio 6.0.2; ROM: 6.0.0

📦 安装步骤

1. 安装依赖

# RN 0.72 版本
npm install react-native-shadow-2@7.0.8

# RN 0.77 版本
npm install react-native-shadow-2@7.1.1

# 或者使用 yarn
yarn add react-native-shadow-2

2. 验证安装

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

{
  "dependencies": {
    "react-native-shadow-2": "^7.0.8"
  }
}

🔧 HarmonyOS 平台配置 ⭐

依赖说明

本库 HarmonyOS 侧实现依赖 react-native-svg 的原生端代码,如已在 HarmonyOS 工程中引入过该库,则无需再次引入。

如未引入,请参照 https://blog.csdn.net/2402_83107102/article/details/159203447

1. 安装 react-native-svg

npm install @react-native-ohos/react-native-svg

2. 引入原生端代码

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

"dependencies": {
  "@react-native-ohos/react-native-svg": "file:../../node_modules/@react-native-ohos/react-native-svg/harmony/svg.har"
}

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

cd entry
ohpm install

3. 配置 CMakeLists

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

set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-svg/src/main/cpp" ./svg)
# RNOH_END: manual_package_linking_1

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_svg)
# RNOH_END: manual_package_linking_2

4. 引入 SvgPackage

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

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SvgPackage.h"

using namespace rnoh;

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

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

import { SvgPackage } from '@react-native-ohos/react-native-svg/ts';

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

📖 API 详解

Shadow 组件

Shadow 组件是本库的核心组件,用于为子组件添加阴影效果。

基本用法

import { Shadow } from 'react-native-shadow-2';

<Shadow>
  <View style={{ width: 100, height: 100, backgroundColor: 'white' }} />
</Shadow>

startColor - 阴影起始颜色

设置阴影的起始渐变色。

类型string

默认值#00000020

使用场景

  • 自定义阴影颜色
  • 创建彩色阴影效果
  • 匹配品牌色调
import { Shadow } from 'react-native-shadow-2';

<Shadow startColor="#eb9066d8">
  <View style={styles.box} />
</Shadow>

<Shadow startColor="#007AFF40">
  <View style={styles.box} />
</Shadow>

endColor - 阴影结束颜色

设置阴影的结束渐变色,与 startColor 配合实现渐变效果。

类型string

默认值:透明

import { Shadow } from 'react-native-shadow-2';

<Shadow startColor="#00000040" endColor="#00000000">
  <View style={styles.box} />
</Shadow>

<Shadow startColor="#FF000080" endColor="#FF000000">
  <View style={styles.box} />
</Shadow>

distance - 阴影延伸距离

设置阴影从组件边缘延伸的距离。

类型number

默认值10

使用场景

  • 控制阴影大小
  • 创建柔和或硬朗的阴影效果
import { Shadow } from 'react-native-shadow-2';

<Shadow distance={5}>
  <View style={styles.box} />
</Shadow>

<Shadow distance={30}>
  <View style={styles.box} />
</Shadow>

offset - 阴影偏移

移动阴影的位置。负 x 值向左移动,负 y 值向上移动。

类型[x: string | number, y: string | number]

默认值[0, 0]

注意:设置此属性会将 paintInside 的默认值设为 true

import { Shadow } from 'react-native-shadow-2';

<Shadow offset={[10, 10]}>
  <View style={styles.box} />
</Shadow>

<Shadow offset={[-10, -10]} startColor="#00000040">
  <View style={styles.box} />
</Shadow>

<Shadow offset={['50%', '10%']}>
  <View style={styles.box} />
</Shadow>

paintInside - 内部绘制

将阴影应用于内容的下方/内部。当使用 offset 属性或子组件包含透明区域时很有用。

类型boolean

默认值false(设置 offset 后默认为 true

import { Shadow } from 'react-native-shadow-2';

<Shadow paintInside startColor="#eb9066d8">
  <View style={styles.box} />
</Shadow>

sides - 边控制

指定将要绘制阴影的边,不包括角落。

类型Record<'start' | 'end' | 'top' | 'bottom', boolean>

默认值:所有边都为 true

import { Shadow } from 'react-native-shadow-2';

<Shadow sides={{ start: false, end: true, top: false, bottom: true }} startColor="#eb9066d8">
  <View style={styles.box} />
</Shadow>

<Shadow sides={{ top: true, bottom: true, start: false, end: false }} distance={20}>
  <View style={styles.box} />
</Shadow>

corners - 角控制

指定将要绘制阴影的角。

类型Record<'topStart' | 'topEnd' | 'bottomStart' | 'bottomEnd', boolean>

默认值:所有角都为 true

import { Shadow } from 'react-native-shadow-2';

<Shadow 
  corners={{ topStart: true, topEnd: true, bottomStart: false, bottomEnd: false }}
  distance={20}
  startColor="red"
>
  <View style={styles.box} />
</Shadow>

style - 子组件容器样式

设置包裹子组件的视图样式。

类型StyleProp<ViewStyle>

import { Shadow } from 'react-native-shadow-2';

<Shadow style={{ backgroundColor: 'white', borderRadius: 10 }}>
  <View style={styles.box} />
</Shadow>

containerStyle - 外层容器样式

设置包裹阴影和子组件的视图样式,对于设置外边距很有用。

类型StyleProp<ViewStyle>

import { Shadow } from 'react-native-shadow-2';

<Shadow containerStyle={{ margin: 20, padding: 10 }}>
  <View style={styles.box} />
</Shadow>

stretch - 水平拉伸

使子组件占据所有可用的水平空间。

类型boolean

默认值false

import { Shadow } from 'react-native-shadow-2';

<Shadow stretch>
  <View style={styles.box} />
</Shadow>

safeRender - 安全渲染

在首次渲染时不使用相对尺寸,而是在后续渲染中采用 onLayout 返回的精确尺寸。用于避免处理半径大于边尺寸时的视觉瑕疵。

类型boolean

默认值false

import { Shadow } from 'react-native-shadow-2';

<View style={{ width: 200, height: 200 }}>
  <Shadow distance={10} safeRender>
    <View style={{ width: '100%', height: '80%', backgroundColor: 'red' }} />
  </Shadow>
</View>

disabled - 禁用阴影

禁用阴影效果,containerStylestyle 属性仍然会生效。

类型boolean

默认值false

使用场景

  • 条件渲染阴影
  • 组件复用
import { Shadow } from 'react-native-shadow-2';

<Shadow disabled={isDarkMode}>
  <View style={styles.box} />
</Shadow>

📋 完整示例

在这里插入图片描述

import React from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  SafeAreaView,
  StatusBar,
} from 'react-native';
import { Shadow } from 'react-native-shadow-2';

const App: React.FC = () => {
  return (
    <SafeAreaView style={styles.container}>
      <StatusBar barStyle="dark-content" backgroundColor="#FFFFFF" />
      <View style={styles.header}>
        <Text style={styles.headerTitle}>阴影效果演示</Text>
      </View>

      <ScrollView style={styles.content}>
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>基础阴影</Text>
          
          <View style={styles.row}>
            <Shadow>
              <View style={styles.box}>
                <Text style={styles.boxText}>默认</Text>
              </View>
            </Shadow>

            <Shadow distance={20}>
              <View style={styles.box}>
                <Text style={styles.boxText}>大距离</Text>
              </View>
            </Shadow>
          </View>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>彩色阴影</Text>
          
          <View style={styles.row}>
            <Shadow startColor="#FF6B6B40" distance={15}>
              <View style={[styles.box, { backgroundColor: '#FF6B6B' }]}>
                <Text style={styles.boxText}>红色</Text>
              </View>
            </Shadow>

            <Shadow startColor="#4ECDC440" distance={15}>
              <View style={[styles.box, { backgroundColor: '#4ECDC4' }]}>
                <Text style={styles.boxText}>青色</Text>
              </View>
            </Shadow>

            <Shadow startColor="#FFE66D40" distance={15}>
              <View style={[styles.box, { backgroundColor: '#FFE66D' }]}>
                <Text style={[styles.boxText, { color: '#333' }]}>黄色</Text>
              </View>
            </Shadow>
          </View>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>渐变阴影</Text>
          
          <View style={styles.row}>
            <Shadow startColor="#667eea80" endColor="#764ba200" distance={20}>
              <View style={[styles.box, { backgroundColor: '#667eea' }]}>
                <Text style={styles.boxText}>渐变1</Text>
              </View>
            </Shadow>

            <Shadow startColor="#f093fb80" endColor="#f5576a00" distance={20}>
              <View style={[styles.box, { backgroundColor: '#f093fb' }]}>
                <Text style={styles.boxText}>渐变2</Text>
              </View>
            </Shadow>
          </View>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>偏移阴影</Text>
          
          <View style={styles.row}>
            <Shadow offset={[10, 10]} startColor="#00000030">
              <View style={styles.box}>
                <Text style={styles.boxText}>右下</Text>
              </View>
            </Shadow>

            <Shadow offset={[-10, -10]} startColor="#00000030">
              <View style={styles.box}>
                <Text style={styles.boxText}>左上</Text>
              </View>
            </Shadow>
          </View>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>边控制</Text>
          
          <Shadow 
            sides={{ start: false, end: false, top: true, bottom: true }}
            distance={15}
            startColor="#007AFF40"
          >
            <View style={[styles.wideBox, { backgroundColor: '#007AFF' }]}>
              <Text style={styles.boxText}>仅上下边阴影</Text>
            </View>
          </Shadow>

          <View style={{ height: 16 }} />

          <Shadow 
            sides={{ start: true, end: true, top: false, bottom: false }}
            distance={15}
            startColor="#34C75940"
          >
            <View style={[styles.wideBox, { backgroundColor: '#34C759' }]}>
              <Text style={styles.boxText}>仅左右边阴影</Text>
            </View>
          </Shadow>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>圆角卡片</Text>
          
          <Shadow 
            distance={20}
            startColor="#00000020"
            style={{ borderRadius: 16 }}
          >
            <View style={styles.card}>
              <Text style={styles.cardTitle}>卡片标题</Text>
              <Text style={styles.cardContent}>
                这是一个带有圆角和阴影效果的卡片组件,展示了 react-native-shadow-2 的强大功能。
              </Text>
            </View>
          </Shadow>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>内部绘制</Text>
          
          <View style={styles.row}>
            <Shadow paintInside startColor="#FF3B3020" distance={10}>
              <View style={[styles.box, { backgroundColor: 'rgba(255,59,48,0.3)' }]}>
                <Text style={styles.boxText}>透明</Text>
              </View>
            </Shadow>

            <Shadow offset={[5, 5]} paintInside startColor="#5856D630">
              <View style={styles.box}>
                <Text style={styles.boxText}>偏移+内部</Text>
              </View>
            </Shadow>
          </View>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>拉伸模式</Text>
          
          <Shadow stretch distance={10} startColor="#00000020">
            <View style={[styles.stretchBox, { backgroundColor: '#FF9500' }]}>
              <Text style={styles.boxText}>拉伸填充</Text>
            </View>
          </Shadow>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionTitle}>禁用阴影</Text>
          
          <View style={styles.row}>
            <Shadow disabled={false} distance={10}>
              <View style={styles.box}>
                <Text style={styles.boxText}>启用</Text>
              </View>
            </Shadow>

            <Shadow disabled={true} distance={10}>
              <View style={styles.box}>
                <Text style={styles.boxText}>禁用</Text>
              </View>
            </Shadow>
          </View>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F5F5',
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 16,
    backgroundColor: '#FFFFFF',
    borderBottomWidth: 1,
    borderBottomColor: '#E5E5EA',
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: '700',
    color: '#333333',
  },
  content: {
    flex: 1,
    padding: 16,
  },
  section: {
    backgroundColor: '#FFFFFF',
    borderRadius: 12,
    padding: 16,
    marginBottom: 16,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: '600',
    color: '#333333',
    marginBottom: 16,
  },
  row: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    flexWrap: 'wrap',
    gap: 16,
  },
  box: {
    width: 80,
    height: 80,
    backgroundColor: '#007AFF',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
  },
  wideBox: {
    width: '100%',
    height: 60,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
  },
  stretchBox: {
    height: 60,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
  },
  boxText: {
    color: '#FFFFFF',
    fontSize: 14,
    fontWeight: '600',
  },
  card: {
    width: '100%',
    backgroundColor: '#FFFFFF',
    borderRadius: 16,
    padding: 20,
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: '700',
    color: '#333333',
    marginBottom: 8,
  },
  cardContent: {
    fontSize: 14,
    color: '#666666',
    lineHeight: 20,
  },
});

export default App;

⚠️ 注意事项

1. 依赖 react-native-svg

本库强依赖 react-native-svg,请确保已正确安装和配置:

npm install @react-native-ohos/react-native-svg

2. 颜色格式

颜色支持以下格式:

  • 十六进制:#RRGGBB#RRGGBBAA
  • RGBA:rgba(r, g, b, a)

推荐使用带透明度的十六进制格式:#00000040

3. 性能优化

  • 避免在列表项中使用过于复杂的阴影效果
  • 对于静态内容,考虑使用图片替代
  • 使用 disabled 属性在不需要时禁用阴影

4. 圆角处理

当使用圆角时,确保 Shadow 组件的 style 和子组件的圆角一致:

<Shadow style={{ borderRadius: 16 }} distance={10}>
  <View style={{ borderRadius: 16, backgroundColor: 'white' }} />
</Shadow>

5. 布局影响

阴影会增加组件的实际占用空间,使用 containerStyle 设置外边距:

<Shadow containerStyle={{ margin: 20 }} distance={10}>
  <View style={styles.box} />
</Shadow>

6. 安全渲染

对于圆形或半径大于边尺寸的情况,使用 safeRender 避免视觉瑕疵:

<Shadow safeRender distance={50}>
  <View style={{ width: 100, height: 100, borderRadius: 50 }} />
</Shadow>
Logo

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

更多推荐