高性能阴影视图组件
| Files | Last commit | Last update |
|---|---|---|
| 3 years ago | ||
| 18 days ago | ||
| 18 days ago | ||
| 19 days ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 28 days ago | ||
| 19 days ago | ||
| 18 days ago | ||
| 18 days ago | ||
| 1 month ago | ||
| 18 days ago | ||
| 1 month ago |
本项目基于 react-native-fast-shadow 开发。如果在使用过程中有任何问题,可以在 GitCode 提交 Issue,会及时跟进。
项目介绍
react-native-fast-shadow 是 React Native 生态的高性能阴影组件库。本项目为其 HarmonyOS(RNOH / Fabric 架构)适配版本,npm 包名为 @hxa-rn/react-native-fast-shadow,业务别名为 react-native-fast-shadow(鸿蒙侧 HAR 的 ohpm 包名为 @oh-rn/react-native-fast-shadow),适配基线为上游 v0.1.1。
对外提供两个能力:
ShadowedView—— 阴影包裹容器组件,是<View>的直接替代品。读取标准shadowColor/shadowOpacity/shadowRadius/shadowOffset样式,在原生侧经 ArkUIshadow()绘制盒外投影,并自动从自身或直接子节点的样式推断投影圆角。shadowStyle()—— 跨端阴影样式工具函数,用于统一各平台的阴影观感;鸿蒙平台模糊半径按原值输出,不做 iOS 式减半。
投影绘制在容器盒外,不占用内容区域。
集成指南
本节用于接入已有 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。
1. 安装适配包
当前 npm 适配包为 @hxa-rn/react-native-fast-shadow@0.1.2(与上游基线同号;版本号低于此前发布的 1.0.0,请按精确版本安装),业务别名为 react-native-fast-shadow。在 RN 应用根目录执行:
npm install @hxa-rn/react-native-fast-shadow@0.1.2 --legacy-peer-deps
该 npm 包包含 JS / 类型产物及已构建的 harmony/fast_shadow.har;安装 npm 包不会重新编译原生 HAR。
peerDependencies:{"react-native":">=0.72"}。还需已有可运行的 RNOH 宿主工程。
2. 配置 Metro 并导入
适配包已声明 harmony.alias。宿主 metro.config.js 合并以下配置,并保留原有的自定义设置:
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');
module.exports = mergeConfig(
getDefaultConfig(__dirname),
createHarmonyMetroConfig({
reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
}),
);
业务代码:
import {ShadowedView, shadowStyle} from 'react-native-fast-shadow';
3. 注册鸿蒙原生模块
本包声明了 Autolinking 元数据:CMake 目标 fast_shadow,ohpm 包 @oh-rn/react-native-fast-shadow,C++ / ETS 类 FastShadowPackage。宿主启用 RNOH Autolinking 后,应检查生成的 HAR 依赖、CMake 链接及 C++ / ETS Package 注册是否齐全;已自动注册时不要重复手动注册。
Autolinking 不可用时,保留宿主已有配置,补齐以下四处:
- 在
harmony/entry/oh-package.json5的dependencies追加下项,然后在harmony/entry执行ohpm install并同步工程:
"@oh-rn/react-native-fast-shadow": "file:../../node_modules/@hxa-rn/react-native-fast-shadow/harmony/fast_shadow.har"
- 在
harmony/entry/src/main/cpp/CMakeLists.txt添加子目录,并在已有add_library(rnoh_app ...)之后链接:
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
add_subdirectory("${OH_MODULE_DIR}/@oh-rn/react-native-fast-shadow/src/main/cpp" ./fast_shadow)
# 放在 rnoh_app 目标创建之后:
target_link_libraries(rnoh_app PUBLIC fast_shadow)
- 在
harmony/entry/src/main/cpp/PackageProvider.cpp添加头文件,并把实例加入已有getPackages返回集合(本仓库模板可加入ManualLinkingPackage列表):
#include "FastShadowPackage.h"
// 加入已有 Package 集合:
std::make_shared<rnoh::FastShadowPackage>(ctx)
- 在
harmony/entry/src/main/ets/RNPackagesFactory.ets添加默认导入,并把实例加入已有createRNPackages返回数组:
import FastShadowPackage from '@oh-rn/react-native-fast-shadow';
// 加入 createRNPackages(ctx) 返回数组:
new FastShadowPackage(ctx)
确保宿主 RNApp 使用上述 createRNPackages,并启用 enableCAPIArchitecture: true。完成后重新生成宿主 Bundle、构建并安装 HAP;只刷新 JS 不会加载新增的原生模块。若 HAR 内 RNOH 相对依赖无法解析,在宿主鸿蒙根 oh-package.json5 的 overrides 中将 @rnoh/react-native-openharmony 指向宿主正在使用的同一 RNOH HAR,勿混用 debug/release 或不同版本。
宿主页面接线(Autolinking 与手动接入都需要):ShadowedView 在鸿蒙侧由本库的 ArkTS 组件 FastShadowView 渲染,Autolinking 不会修改宿主页面。请在宿主创建 RNApp 的页面(RNOH 工程模板为 harmony/entry/src/main/ets/pages/Index.ets)补齐以下三处,否则阴影不显示(与本仓示例相同):
import { FastShadowView, FAST_SHADOW_VIEW_TYPE } from '@oh-rn/react-native-fast-shadow';
const ARK_TS_COMPONENT_NAMES: string[] = [FAST_SHADOW_VIEW_TYPE];
@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
// 保留宿主已有的分支,追加:
if (ctx.componentName === FAST_SHADOW_VIEW_TYPE) {
FastShadowView({ ctx: ctx.rnComponentContext, tag: ctx.tag });
}
}
const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
// RNApp 参数中:
RNApp({
rnInstanceConfig: {
createRNPackages,
enableCAPIArchitecture: true,
arkTsComponentNames: ARK_TS_COMPONENT_NAMES,
// ...保留宿主原有配置
},
wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
// ...保留宿主原有参数
})
本库本体不要求额外系统权限。
使用说明
基础用法
import { ShadowedView } from 'react-native-fast-shadow';
<ShadowedView
style={{
shadowColor: '#1e88e5',
shadowOpacity: 0.6,
shadowRadius: 12,
shadowOffset: { width: 0, height: 4 },
borderRadius: 16,
backgroundColor: '#ffffff',
}}
>
<View style={{ width: 160, height: 100 }} />
</ShadowedView>
配合 shadowStyle() 保持跨端一致
import { ShadowedView, shadowStyle } from 'react-native-fast-shadow';
<ShadowedView
style={shadowStyle({
color: '#1e88e5',
opacity: 0.6,
radius: 12,
offset: [0, 4],
})}
>
<View style={{ width: 160, height: 100, borderRadius: 16, backgroundColor: '#fff' }} />
</ShadowedView>
圆角推断规则
投影轮廓的圆角按以下顺序推断,命中即止:
- 自身 style —— 当自身样式含
backgroundColor或任一圆角属性时命中,取自身圆角; - 唯一合法直接子元素的 style —— 自身未命中时,取子元素圆角;
- 两者皆无 —— 四角回落为 0,投影呈直角矩形。
四角取值支持 borderRadius 统一值、borderTopLeftRadius 等四角单角值,以及 borderTopStartRadius / borderTopEndRadius 等方向属性;单角值优先于统一值。
接口文档
ShadowedView
阴影包裹容器组件,继承全部标准 ViewProps。
| 样式属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
shadowColor |
ColorValue |
黑色 | 投影颜色。颜色自带的 alpha 通道被剥离,浓淡仅由 shadowOpacity 决定;不可解析的颜色回落默认黑 |
shadowOpacity |
number |
0 |
投影不透明度。≤ 0(含负值)完全不绘制;> 1 按全不透明处理 |
shadowRadius |
number |
3 |
模糊半径(vp)。有效范围 [0, 25],越界按边界钳制;取整到最近 0.5 |
shadowOffset |
{ width: number; height: number } |
{ width: 0, height: -3 } |
投影偏移(vp)。正值分别向右、向下 |
| 圆角属性 | number |
0 |
参与圆角推断,规则见「使用说明」 |
返回值:React 组件。
异常:不抛出任何异常,无错误码。非法或缺省的样式值一律按上表默认值回落,不中断渲染。
标准容器属性:testID、onLayout、pointerEvents 等全量透传给底层组件。
shadowStyle(params)
生成标准阴影样式对象的工具函数。
参数 params: ShadowParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
color |
ColorValue |
否 | 原样赋给 shadowColor |
opacity |
number |
否 | 原样赋给 shadowOpacity |
radius |
number |
否 | 赋给 shadowRadius。鸿蒙平台输出原值;iOS 平台输出输入值的一半 |
offset |
[number, number] |
否 | 转为 { width: offset[0], height: offset[1] } |
返回值 ViewStyle —— 含 shadowColor / shadowOpacity / shadowRadius / shadowOffset 四个键的样式对象。入参字段缺省时对应输出为 undefined;radius: 0 时字段值为 0(与「未提供」不同,后者字段不存在)。
异常:不抛出。
ShadowParams
shadowStyle() 的入参类型,字段定义见上表。
与其他平台的行为差异
| 项 | 鸿蒙 | 上游 Android / iOS |
|---|---|---|
shadowStyle() 的 radius |
原值输出 | iOS 输出一半(上游认为 iOS 视觉半径偏大一倍) |
| 半径与圆角取整 | 四舍五入到最近 0.5 | 上游 Android 实为向下取整到整数(其代码与注释不符),鸿蒙按上游注释的设计意图实现 |
| 投影形状 | 仅圆角矩形 | Android 同;iOS 支持任意形状 |
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 |
|---|---|
| Node.js | >= 20(示例工程 engines 要求);DevEco Sync 时 ohpm preInstall 钩子也要用 PATH 中的 Node.js 与 npm |
| DevEco Studio | 6.1.1 及以上(示例 targetSdkVersion 为 6.1.1(24)) |
| HarmonyOS SDK | API 18+(example/harmony 的 compatibleSdkVersion 为 5.1.0(18)) |
| 路径 | Windows 下仓库根目录的完整路径不超过 40 个字符,否则原生构建的中间文件路径会超过系统上限 |
运行步骤
1. 克隆仓库
git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-fast-shadow.git
cd react-native-fast-shadow
Windows 下可在克隆时指定短目录名,例如 git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-fast-shadow.git C:\rfs。
2. 进入 example 目录,安装依赖
cd example
npm install --legacy-peer-deps
Example 从 npm 公仓安装 @hxa-rn/react-native-fast-shadow@0.1.2,不需要在仓根执行 npm pack。
3. 生成 JS Bundle
npm run dev
产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js
4. 用 DevEco Studio 打开鸿蒙工程
- 打开 DevEco Studio,选择
example/harmony目录 - 首次构建请在 File → Project Structure → Signing Configs 勾选 Automatically generate signature,Apply 后 Sync
- 等待 Sync 完成
5. 编译并运行 HAP
在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备。
example_auto(自动化用例工程)步骤相同,把 example 换成 example_auto 即可,两者的依赖与构建输出相互独立。
注意:Example 已预置 Package 注册、Metro alias 与 HAR 依赖,无需手动 Link。编 HAP 前必须先执行
npm run dev;改过 JS 后重新执行再运行。首次 Sync 时 ohpmpreInstall钩子会在仓根补跑一次准备脚本(需联网,已完成的部分自动跳过)。
常见问题
- 找不到 JS 模块:检查适配包安装、Metro 别名及对应入口,修改 Metro 后重启打包进程。
- 找不到 npm 包或 HAR:核对
example/node_modules/@hxa-rn/react-native-fast-shadow/harmony/fast_shadow.har是否存在,必要时在example目录重新执行npm install --legacy-peer-deps;不要将example_auto的 node_modules 当成example的依赖。 - 原生模块或组件未注册:检查 HAR、CMake、C++ 和 ETS 注册,排除重复注册并重建 HAP。
- SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
- Ninja
.rsp创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。
约束与限制
| 项 | 说明 |
|---|---|
| 支持形状 | 仅支持圆角矩形投影,不支持任意形状。文字投影请使用 textShadowRadius |
| 子节点尺寸 | 应填满容器:ShadowedView 与其子节点尺寸不一致时,投影会大于内容 |
| 圆角推断 | 视图层级较深时推断链可能落空,此时请直接给 ShadowedView 的 style 传 borderRadius |
| 模糊半径范围 | [0, 25]:负值按 0 渲染,超过 25 按 25 渲染。取整到最近 0.5 |
| 颜色 alpha | shadowColor 的 alpha 通道不参与,投影浓淡仅由 shadowOpacity 决定 |
| 默认偏移 | 未提供 shadowOffset 时按 (0, -3) 呈现(向上偏移),而非 (0, 0) |
| RTL | 布局镜像即时生效;圆角起始/结束方向映射取决于 JS 侧 I18nManager.isRTL,运行时 forceRTL 不刷新该常量且重启不持久,需系统级 RTL 环境才生效 |
| 权限 | 不申请任何系统权限 |
| 兼容性 | 鸿蒙 SDK minAPIVersion 5.0.1(13);已验证环境 RN 0.72.5 / RNOH 0.72.139 |
| 设备类型 | HAR module.json 声明 default / tablet / 2in1 |
| 自动链接 | 当前根 package.json 已声明 harmony.autolinking;宿主启用自动链接后检查生成结果,不可用时按集成指南手动注册 |
开源 License
本项目基于 MIT License 开源,与上游 react-native-fast-shadow 协议一致。请自由地享受和参与开源。
问题反馈渠道
使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。