react-native-radial-gradient:基于 React Native 鸿蒙生态的径向渐变组件适配项目

径向渐变色视图组件

Branch3Tags2

react-native-radial-gradient

本项目基于 react-native-radial-gradient 开发。如果在使用过程中有任何问题,可以在GitCode提交Issue,会及时跟进。

项目介绍

react-native-radial-gradient(当前 npm 版本 1.2.1,与上游基线同号)为 React Native 提供径向渐变视图:以一个中心点为原点、按半径向外做多色渐变填充,并可承载子内容(children 叠加在渐变之上)。

核心能力:

  • 多色渐变:colors 按数组顺序由内向外分布;未给停靠位时按颜色数量均分。
  • 单色渐隐:只给一个颜色时自动扩展为该色的五档透明度序列(不透明 → 完全透明)。
  • 停靠位控制:stops 与颜色数量相等时逐一对应,可做出偏心的色带分布。
  • 中心与半径:center、radius 均以 vp 为单位;缺省时回落到组件区域中心与短边的一半。
  • 边界填充:半径之外的区域由颜色序列的末位颜色填满整个组件盒,不留空白、不重复色环。
  • 子内容层叠:children 始终渲染在渐变层之上,不被遮挡。
  • 支持平台:Android、iOS、OpenHarmony(OHOS)。

鸿蒙侧基于 ArkUI 通用属性 .radialGradient() 实现,无自绘、无线程模型、无持久化,不申请任何系统权限。组件为 Fabric 新架构原生视图(SRSRadialGradient),不向 JS 侧发送任何事件。

集成指南

本节用于接入已有 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。

1. 安装适配包

当前 npm 适配包为 @hxa-rn/react-native-radial-gradient@1.2.2,业务别名为 react-native-radial-gradient。在 RN 应用根目录安装:

npm install @hxa-rn/react-native-radial-gradient@1.2.2 --legacy-peer-deps

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 RadialGradient from '@hxa-rn/react-native-radial-gradient/index.harmony';

3. 注册鸿蒙原生模块

本包声明了 Autolinking 元数据:CMake 目标 radial_gradient,ohpm 包 @oh-rn/react-native-radial-gradient,C++ / ETS 类 RadialGradientPackage。宿主启用 RNOH Autolinking 后,应检查生成的 HAR 依赖、CMake 链接及 C++ / ETS Package 注册是否齐全;已自动注册时不要重复手动注册。

Autolinking 不可用时,保留宿主已有配置,补齐以下四处:

  1. 在 harmony/entry/oh-package.json5 的 dependencies 追加下项,然后在 harmony/entry 执行 ohpm install 并同步工程:
"@oh-rn/react-native-radial-gradient": "file:../../node_modules/@hxa-rn/react-native-radial-gradient/harmony/radial_gradient.har"
  1. 在 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-radial-gradient/src/main/cpp" ./radial_gradient)
# 放在 rnoh_app 目标创建之后:
target_link_libraries(rnoh_app PUBLIC radial_gradient)
  1. 在 harmony/entry/src/main/cpp/PackageProvider.cpp 添加头文件,并把实例加入已有 getPackages 返回集合(本仓库模板可加入 ManualLinkingPackage 列表):
#include "RadialGradientPackage.h"

// 加入已有 Package 集合:
std::make_shared<rnoh::RadialGradientPackage>(ctx)
  1. 在 harmony/entry/src/main/ets/RNPackagesFactory.ets 添加默认导入,并把实例加入已有 createRNPackages 返回数组:
import RadialGradientPackage from '@oh-rn/react-native-radial-gradient';

// 加入 createRNPackages(ctx) 返回数组:
new RadialGradientPackage(ctx)

确保宿主 RNApp 使用上述 createRNPackages,并启用 enableCAPIArchitecture: true。完成后重新生成宿主 Bundle、构建并安装 HAP;只刷新 JS 不会加载新增的原生模块。若 HAR 内 RNOH 相对依赖无法解析,在宿主鸿蒙根 oh-package.json5 的 overrides 中将 @rnoh/react-native-openharmony 指向宿主正在使用的同一 RNOH HAR,勿混用 debug/release 或不同版本。

Babel 配置:不要全局关闭静态 ViewConfig codegen

若宿主工程为兼容某个分发编译后 JS(无 TS 泛型)的其他 RNOH 库,在 babel.config.js 里设置了 disableStaticViewConfigsCodegen: true,不要把这个选项设成全局。本库的 RadialGradientNativeComponent.ts 是完整 TS 泛型源码,依赖静态 ViewConfig codegen 才能被 Fabric 正确发现;全局关闭会让它退回运行时 UIManager.getViewManagerConfig 查找,而该查找在 RNOH 上对本库这类手动注册的组件不成立,导致运行时报 Invariant Violation: View config not found for component 'SRSRadialGradient'。

正确做法是用 Babel 的 overrides 把这个选项限定到需要它的那个库的文件路径,默认预设保持开启:

module.exports = {
  presets: ['module:@react-native/babel-preset'],
  overrides: [
    {
      test: /[\\/]@oh-rn[\\/]react-native-some-other-lib[\\/]/,
      presets: [
        ['module:@react-native/babel-preset', {disableStaticViewConfigsCodegen: true}],
      ],
    },
  ],
};

本库无额外系统权限;业务使用上面的 index.harmony 入口,与本仓库 example 保持一致。

使用说明

import React from 'react';
import { Text, View } from 'react-native';
import RadialGradient from '@hxa-rn/react-native-radial-gradient/index.harmony';

export default function Demo() {
  return (
    <View>
      {/* 多色:绿 → 黄 → 蓝,由内向外均分 */}
      <RadialGradient
        style={{ width: 200, height: 200 }}
        colors={['#00E676', '#FFD600', '#2979FF']}>
        <Text>叠加在渐变之上的子内容</Text>
      </RadialGradient>

      {/* 指定停靠位:黄色环靠近中心 */}
      <RadialGradient
        style={{ width: 200, height: 200 }}
        colors={['#00E676', '#FFD600', '#2979FF']}
        stops={[0, 0.15, 1]}
      />

      {/* 指定中心与半径:半径之外由末位颜色蓝色填满 */}
      <RadialGradient
        style={{ width: 200, height: 200 }}
        colors={['#00E676', '#2979FF']}
        center={[40, 40]}
        radius={40}
      />

      {/* 单色:自动扩展为五档透明度渐隐 */}
      <RadialGradient
        style={{ width: 200, height: 200 }}
        colors={['#00E676']}
      />
    </View>
  );
}

接口文档

组件对外仅一个默认导出 RadialGradient,无方法型接口、无事件回调。

属性 类型 必填 缺省 说明
colors string[] 是 未给或空数组时回落为红到蓝双色 渐变色序列,由内向外分布。只给一个颜色时扩展为该色的五档透明度渐隐
center number[] 否 组件区域中心 (宽/2, 高/2) 渐变中心 [x, y],单位 vp。长度不为 2 时整体忽略
stops number[] 否 按颜色数量均分 各颜色的停靠位,取值 [0, 1]。长度与最终颜色数不相等时整串丢弃并改为均分;空数组等同于未传
radius number 否 min(宽, 高) / 2 渐变半径,单位 vp。小于 1 时忽略并回落到缺省值
style 及其余 ViewProps ViewProps 否 — 透传给外层容器视图
children ReactNode 否 — 叠加在渐变层之上,不被渐变遮挡

使用注意事项:

  • colors 中无法解析的颜色项不会被剔除,而是以完全透明参与渲染,有效色数不减少 —— 表现为相邻两色之间出现一圈透明过渡环。若不希望如此,请在传入前自行过滤。
  • 支持带透明度的颜色写法(如 'transparent'、'rgba(0,230,118,0)'、'#00E67600'),该项渲染为完全透明。
  • stops 的长度必须与最终颜色数相等才会生效。注意只给一个颜色时会先扩展为五档,此时若要指定停靠位需给出 5 个值。
  • center 与 radius 的缺省值依赖组件的实际渲染尺寸:首次布局测量完成前不渲染渐变,测量完成后自动补画,无需额外交互触发。
  • 半径小于组件半盒时,半径之外的区域(含四角)由末位颜色填满,不留空白、不透明、不重复色环。

快速验证(运行 Example)

前置条件

依赖 版本要求
Node.js >= 20(示例工程 engines 要求)
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-radial-gradient.git
cd react-native-radial-gradient

Windows 下可在克隆时指定短目录名,例如 git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-radial-gradient.git C:\rrg。

2. 进入 example 目录,安装依赖

cd example
npm install --legacy-peer-deps

Example 从 npm 公仓安装 @hxa-rn/react-native-radial-gradient@1.2.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 后重新执行再运行。

常见问题

  • 找不到 JS 模块:检查适配包安装、Metro 别名及对应入口,修改 Metro 后重启打包进程。
  • 找不到 npm 包或 HAR:核对当前目录、安装版本及 node_modules/@hxa-rn/react-native-radial-gradient/harmony/radial_gradient.har;不要将 example_auto 的 node_modules 当成 example 的依赖。
  • 原生模块或组件未注册:检查 HAR、CMake、C++ 和 ETS 注册,排除重复注册并重建 HAP。
  • SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
  • Ninja .rsp 创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。

约束与限制

  • 上游基线:v1.2.1(MIT);npm 版本 1.2.1;鸿蒙原生模块版本 1.2.1-ohos.1。
  • React Native:0.72.5;RNOH 框架:@react-native-oh/react-native-harmony 0.72.143。
  • 示例工程 compatibleSdkVersion:5.1.0(18),targetSdkVersion:6.1.1(24),runtimeOS:HarmonyOS(HAR 未单独声明 API 下限);已在真机 HarmonyOS 6.1(API 24)验证通过,三种用法(多色均分、指定停靠位、单色透明度渐隐)均渲染正确。
  • 底层依赖 ArkUI 通用属性 .radialGradient()(起始版本 API 7)与 onAreaChange,均远低于示例工程的最低兼容 API。
  • 支持设备类型:default / tablet / 2in1。
  • 权限:无。 HAR 模块 module.json5 的 requestPermissions 为空数组,不联网、不采集任何设备标识。
  • 已声明平台:Android、iOS、OpenHarmony(OHOS)。
  • 渲染语义以上游 Android 实现为契约源头。上游 iOS 在停靠位均分与单色特化上与 Android 存在差异(属上游既有行为),鸿蒙侧对齐 Android。
  • 本库 npm 包名为 @hxa-rn/react-native-radial-gradient;HAR 内 ohpm 模块名为 @oh-rn/react-native-radial-gradient,两者用途不同,不能全局替换。

开源 License

本项目基于 MIT License 开源,与上游 react-native-radial-gradient 保持一致。

问题反馈渠道

使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。