React Native for OpenHarmony 实战:三方库 react-native-paper 的鸿蒙化适配指南
本文记录把 react-native-paper(Material Design 组件库)适配到 HarmonyOS 的完整过程。
它做的事:一整套 Material Design 3 组件 —— Button / Card / Chip / FAB / TextInput / Dialog / Appbar / DataTable / Snackbar / Drawer …,
外加主题系统(Provider + useTheme + MD3Colors)。
结论:可用 —— 而且这是这几轮里"组件渲染证据最实在"的一次。
主入口共 57 个导出、20 个关键导出全部存在,useTheme() 返回了真实的 MD3 主题
(colors 33 个键、primary = rgba(103, 80, 164, 1)),
并且 Button / Card 的文本在布局里拿到了真实坐标(x=504 y=1293、x=108 y=1903 等)。
本文还记下 4 个技术发现:两个纯 JS 桩的写法、00308018 的真正修法、设备锁屏导致的假失败,以及一个我自己踩的接线脚本 bug。
★★★★★ 一、预检:大库但很干净,只缺两个"带资源"的依赖
| 预检项 | 结果 |
|---|---|
老写法九项(createClass / React.PropTypes / ViewPropTypes / Text.propTypes / 字符串 ref / this.refs / mixins / componentWillReceiveProps / componentWillMount / getDefaultProps) | ✅✅ 全部为空 |
ListView / isRequired | ✅ 空 |
measure() | 3 处,只在 Tooltip 里 |
Platform.OS 171 处 / useNativeDriver 165 处 | 大库必然的分支 |
NativeModules 6 处 | ✅ 全在 Switch.tsx,写法是 NativeModules.PlatformConstants ? …reactNativeVersion : undefined ⇒ 有三元保护,不崩 |
dependencies 3 个 | ⚠️ @callstack/react-theme-provider / color / use-latest-callback ⇒ 必须显式装(file: 接入不会自动装) |
peerDependencies | ⚠️ react-native-safe-area-context(src 里 27 处) |
| 图标 | ⚠️ @expo/vector-icons 的 MaterialCommunityIcons(27 处) |
| 规模 | 1206 文件、src/ 174 个、lib/commonjs + lib/module + lib/typescript + react-navigation/ |
⇒ 两个"带原生资源"的依赖(safe-area-context 要接窗口 inset、vector-icons 要打字体)不装,改用纯 JS 桩隔离 ——
这样才能判断"paper 本身在鸿蒙上是否可用"。
★★★★★ 二、两个纯 JS 桩:怎么让 paper 在"缺依赖"的情况下跑起来
桩 1:react-native-safe-area-context
paper 的 src 里用到四个符号:SafeAreaProvider / SafeAreaView / useSafeAreaInsets / SafeAreaInsetsContext,
其中 useSafeAreaInsets() 必须返回一个含 top/right/bottom/left 的对象(调用方会解构)。
const INSETS = {top: 39, right: 0, bottom: 0, left: 0}; // 本机实测状态栏 117px = 39vp
const SafeAreaInsetsContext = React.createContext(INSETS);
const useSafeAreaInsets = () => React.useContext(SafeAreaInsetsContext) || INSETS;
const SafeAreaProvider = ({children}) =>
React.createElement(SafeAreaInsetsContext.Provider, {value: INSETS}, children);
const SafeAreaView = React.forwardRef(({edges, mode, style, ...rest}, ref) =>
React.createElement(View, {ref, style, ...rest}));
⇒ 把 top 填 39(真机实测值)而不是 0 ⇒ 让"避让安全区"的行为尽量接近真实。
桩 2:@expo/vector-icons
只需要"默认导出 MaterialCommunityIcons,且能当组件渲染、接受 name/size/color":
const FakeIcon = ({name, size = 24, color = '#000'}) => {
const label = String(name).slice(0, 1).toUpperCase();
// 一个 size×size 的带边框小方块 + 首字母
return <View style={{width: size, height: size, borderWidth: 1, borderColor: color, …}}>
<Text style={{color, fontSize: size * 0.6}}>{label}</Text>
</View>;
};
MaterialCommunityIcons.glyphMap = new Proxy({}, {get: (_t, p) => String(p)}); // ★ 需要 glyphMap
MaterialCommunityIcons.getImageSource = () => Promise.resolve(null);
MaterialCommunityIcons.loadFont = () => Promise.resolve();
⇒ 关键是要提供 glyphMap(paper 会用它把图标名映射成字形)—— 用一个 Proxy 兜住任意名字即可。
⇒ 用"小方块 + 首字母"而不是返回 null,这样图标的位置和尺寸也能在布局 dump 里看见 ✓
两个桩都通过 metro.config.js 的 extraNodeModules 顶掉:
'react-native-safe-area-context': path.resolve(__dirname, 'stubs/react-native-safe-area-context.js'),
'@expo/vector-icons': path.resolve(__dirname, 'stubs/expo-vector-icons.js'),
'react-native-vector-icons': path.resolve(__dirname, 'stubs/expo-vector-icons.js'),
⇒ paper 本体一行没改,成功 bundle + 构建 + 运行 ✓
★★★★★ 三、实证:57 个导出、真实主题、真实组件坐标
导出契约(一次全过)
NOTE | 导出总数(Object.keys 计数) = 57
PASS | ★★ 导出总数 > 20(大库)
NOTE | 导出的前 40 个键 = ActivityIndicator, AnimatedFAB, Appbar, Avatar, Badge, Banner,
BottomNavigation, Button, Caption, Card, Checkbox, Chip, DataTable, DefaultTheme, Dialog,
Divider, Drawer, FAB, Headline, HelperText, Icon, IconButton, List, MD2Colors, MD3Colors,
Menu, Modal, PaperProvider, Paragraph, Portal, ProgressBar, Provider, RadioButton,
Searchbar, SegmentedButtons, Snackbar, Subheading, Surface, Switch, Text …
NOTE | 缺失的关键导出 = (无)
PASS | ★★★ 20 个关键导出全部存在 ← 期望=0 | 实际=0
这次我特意"只断言存在、不猜 typeof"(因为此前连续在这上面出错),形态只记在 NOTE 里:
NOTE | Provider = function
NOTE | Button = object ← forwardRef
NOTE | Card = object ← forwardRef
NOTE | Chip = function
NOTE | FAB = object ← forwardRef
NOTE | TextInput = object ← forwardRef
NOTE | Dialog = function
⇒ ⇒ 印证了一件事:paper 的组件大多是 forwardRef ⇒ typeof 是 object 而不是 function。
⇒ 如果我这次写了"Button 是 function"的断言,就会白白多一条 FAIL。 这一步的克制是对的 ✓
主题系统真的在工作
NOTE | useTheme() 返回的键 = dark, roundness, version, isV3, colors, fonts, animation
NOTE | useTheme().dark = false
NOTE | useTheme().colors 的键数 = 33
NOTE | useTheme().colors.primary = rgba(103, 80, 164, 1)
PASS | ★★ DefaultTheme 存在且有 colors
⇒ rgba(103, 80, 164, 1) 正是 Material Design 3 的默认主色(紫)✓✓
⇒ colors 有 33 个键 —— 这是一整套完整的 MD3 调色板,说明主题系统整体可用 ✓
组件文本拿到了真实坐标
用布局 dump 里的 Text 节点坐标来定位"组件真的渲染出来了":
✓ 「PAPER 描边按钮」 w=312 h=60 x=504 y=1293 ← Button mode="outlined"
✓ 「PAPER 文本按钮」 w=312 h=60 x=504 y=1431 ← Button mode="text"
✓ 「副标题」 w=1152 h=60 x=108 y=1810 ← Card.Title 的 subtitle
✓ 「这是 Card 的内容区」 w=1104 h=42 x=108 y=1903 ← Card.Content 里的 Text
⇒ ⇒ Button 与 Card 的文本位置、尺寸都对得上,说明这两个组件在鸿蒙上渲染正常 ✓✓
⇒ y=1293 / 1431 / 1810 / 1903 依次递增,与我页面里的书写顺序完全一致 ✓
★★★★★ 四、技术发现:00308018 的真正修法
这一轮的构建第一次是失败的:
> hvigor ERROR: Failed :entry:default@BuildNativeWithNinja...
> hvigor ERROR: Error Code: 00308018 Unknown Error
FAILED: [code=1] .../obj/arm64-v8a/libjsi.so
ninja: build stopped: subcommand failed
而 bundle exit=0(JS 打包是好的)⇒ 失败在原生侧(libjsi.so)。
当时还有一条容易被忽略的线索:
[metro] [Fail]TCP Port listen failed at 8081
修法:清掉 .hvigor 与 entry/.cxx 两个缓存目录,然后全量重编
cd E:\rnoh-work\RNOH084Demo\harmony
Remove-Item '.hvigor' -Recurse -Force
Remove-Item 'entry\.cxx' -Recurse -Force
hvigorw --mode module -p product=default -p module=entry@default assembleHap --no-daemon
结果:
> hvigor BUILD SUCCESSFUL in 16 min 51 s 952 ms
hap 时间戳 = 10/17/2026 16:58:46
⇒ ⇒ 成功,但耗时 16 分 51 秒(因为 .cxx 清掉后是全量重编 C++,而平时增量只要 3~4 分钟)✓
这条经验值得记下来:
00308018+libjsi.soFAILED +ninja: build stopped⇒
这不是 JS/依赖问题(bundle exit=0已经排除),而是 CMake/Ninja 缓存损坏 ⇒
清.hvigor与entry/.cxx全量重编 即可恢复(代价是 17 分钟)。
★★★★ 五、一个假失败:设备锁屏
第一次安装后的启动结果是:
error: failed to start ability.
Error Code:10106102 Error Message: The device screen is locked during the application launch,
unlock screen failed.
Error cause: The current mode is developer mode, and the screen cannot be unlocked automatically
⇒ App 根本没启动 ⇒ 判据 0 行、所有文本"未找到"、四张截图都是锁屏画面
⇒ 如果这时候我就下结论,会得出"paper 在鸿蒙上跑不起来"的错误判断 ✗
修法:
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500 # 上滑解锁
hdc shell uinput -T -m 660 1900 660 500 # 再滑一次更稳
⇒ 之后再启动 ⇒ start ability successfully ✓
教训:
10106102是"设备锁屏"而不是"App 崩溃"。
遇到"启动失败 + 判据全无输出 + 截图不像我的页面"时,先看一眼启动命令的返回值,
不要急着怀疑库。
★★★ 六、一个我自己的接线 bug(值得记)
我给宿主工程加依赖时写了一段 PowerShell:
foreach ($pair in @(@('react-native-paper', 'file:../react-native-paper'))) {
$deps | Add-Member -NotePropertyName $pair[0] -NotePropertyValue $pair[1] # ✗
}
问题:@(@('a','b')) 在 PowerShell 里会被展平成一个字符串数组 @('a','b'),
所以 $pair 是 字符串、$pair[0] 取到的是第一个字符 'r'、$pair[1] 是……于是 package.json 里被写进了:
"r": "f"
随后 npm install 报:
npm error code ETARGET
npm error notarget No matching version found for f@i.
⇒ 浪费了两轮构建时间 ✗
修法:用 -split 或直接两步赋值:
$pkgName = 'react-native-paper'
$pkgSpec = 'file:../react-native-paper'
$deps | Add-Member -NotePropertyName $pkgName -NotePropertyValue $pkgSpec -Force
教训:PowerShell 里"嵌套数组"极易被意外展平;要配对的字面量直接写成两个变量最稳。
而且写完package.json要回读校验(我这次是等到npm install报notarget才发现)。
★★ 七、本次的 1 条 FAIL(我猜错了属性名)
NOTE | MD3Colors 的 typeof = object
NOTE | MD3Colors.primary = undefined
FAIL | ★★ MD3Colors 是 object 且有 primary | 期望=true | 实际=false
⇒ MD3Colors 里没有 primary —— 它是一整套调色板刻度
(MD3 的命名是 primary0 / primary10 / … / neutral0 这类),不是"语义色 + primary"那种结构。
真正带 primary 的是 DefaultTheme.colors(实测 colors 33 个键、primary = rgba(103,80,164,1))✓
⇒ ⇒ 教训:MD3Colors 与 DefaultTheme.colors 是两个不同层次的东西,我混为一谈了。
★ 八、其余预检结论
| 预检项 | 结果 |
|---|---|
| 外部 import | @callstack/react-theme-provider / @expo/vector-icons / @react-navigation/native(可选目录)/ color / react / react-native / react-native-safe-area-context / use-latest-callback |
react-navigation/ 目录 | 是可选集成(adaptNavigationTheme 等),主路径不依赖 |
| 交付包形态 | ✅ src/(174 个)+ lib/commonjs + lib/module + lib/typescript ⇒ 源码/产物/类型齐全 |
scripts.prepare | ✅ 空(不需要 --ignore-scripts,但为统一仍带着) |




九、接入与预检(要点)
# ① 装 paper 本体
npm install "git+https://atomgit.com/oh-react-native/react-native-paper.git#5.15.3-ohos-1.0.0" --ignore-scripts
# ② ★ 必须显式装它的 3 个运行时依赖(file: 接入不会自动装)
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4
# ③ safe-area-context 与 图标库 用纯 JS 桩隔离(见正文第二节)
十、交付包质量与基线说明
| 类别 | 结果 |
|---|---|
| 交付包内容 | src/(174 个 ts/tsx)+ lib/commonjs + lib/module + lib/typescript + react-navigation/(可选集成) ⇒ 完整 ✓(1206 文件) |
spec.json | ⚠️ 缺 upstreamCommit |
validation | ⚠️ "build-pass-device-pending" |
| ⚠️ 声明的基线 | reactNative: "0.88.0" + rnoh: "0.84.4" ⇒ 两字段自相矛盾 |
| 备注 | 库代码零改动(本轮只加 polyfill/stub,未改库) |
关于基线:本次验证在 RN 0.84.1 + RNOH 0.84.3 上完成。
Platform.OS 有 171 处分支,但实测运行路径没有踩到会崩的分支 ⇒ 结论可用;换基线时建议重跑。
十一、已知限制与本次验证边界
11.1 用这个库要知道的
| 事项 | 说明 |
|---|---|
| ★★★★★ 有 3 个运行时依赖必须显式装 | color / @callstack/react-theme-provider / use-latest-callback |
★★★★★ react-native-safe-area-context 是 peerDep | 27 处使用;不装需自己写桩(useSafeAreaInsets 要返回 {top,right,bottom,left}) |
★★★★ 图标来自 @expo/vector-icons | 27 处;桩需要提供 glyphMap(可用 Proxy 兜住) |
★★★★ 组件大多是 forwardRef | typeof Button/Card/FAB/TextInput === 'object'(不是 function);Provider/Chip/Dialog 是 function |
★★★★ useTheme() 在 Provider 内可用 | 返回 {dark, roundness, version, isV3, colors, fonts, animation},colors 33 键 |
★★★ MD3Colors ≠ DefaultTheme.colors | 前者是调色板刻度(primary0/primary10…),后者才有语义色 primary |
★★★ NativeModules 只用于读版本号 | 在 Switch.tsx,且有三元保护 ⇒ 鸿蒙上安全 |
| ★★ 主入口 57 个导出 | 20 个关键组件全部存在 |
11.2 本次验证的边界
- ★★★ 未验证 Chip / TextInput / FAB 各自的独立坐标(文本匹配时被我页面上的"判据要点"节点抢先命中);
- ★★★ 未验证
Dialog/Snackbar/Portal/Appbar/DataTable/Drawer等其余 40+ 组件; - ★★★ 未验证交互(
onPress回调未实际点击;TextInput未输入); - ★★ 未验证
MD3与MD2主题切换(只用了默认); - ★★ 未验证
configureFonts自定义字体; - ★★ 未验证深色模式(
dark实测false,未切true); - 未验证
react-navigation/里的adaptNavigationTheme; - 未在
RN 0.88.0/RNOH 0.84.4上复验; - 未测其它屏幕宽度;未做跨平台对照。
库代码未改动(新增的是 stubs/react-native-safe-area-context.js 与 stubs/expo-vector-icons.js)。
十二、常见问题
Q1:它在 RN 0.84 上能跑吗?
能。 57 个导出、20 个关键组件全在;useTheme() 返回真实 MD3 主题(colors.primary = rgba(103,80,164,1));
Button 与 Card 的文本拿到了真实布局坐标(x=504 y=1293 / x=108 y=1903);LogBox 无通知。
Q2:npm install 之后 Unable to resolve module color?
color / @callstack/react-theme-provider / use-latest-callback 是 paper 的 dependencies,
而 file: 接入不会自动装它们 ⇒ 要显式装:
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4
Q3:Unable to resolve module react-native-safe-area-context / @expo/vector-icons?
两个都是"带资源"的库:前者要接窗口 inset(原生),后者要打包字体。
隔离验证时用纯 JS 桩(正文第二节有完整代码):
// 前者:useSafeAreaInsets 返回 {top:39,right:0,bottom:0,left:0}
// 后者:默认导出 MaterialCommunityIcons,并提供 glyphMap(用 Proxy 兜住任意键)
Q4:构建报 00308018 + libjsi.so FAILED?
bundle 是好的、错在原生侧 ⇒ CMake/Ninja 缓存损坏。清缓存全量重编:
cd harmony
Remove-Item '.hvigor' -Recurse -Force
Remove-Item 'entry\.cxx' -Recurse -Force
hvigorw --mode module -p product=default -p module=entry@default assembleHap --no-daemon
⚠️ 会变成全量重编(实测 16 分 51 秒),平时增量只要 3~4 分钟。
Q5:aa start 报 Error Code:10106102 / screen is locked?
设备锁屏了,App 根本没启动(不是崩溃)。先唤醒再解锁:
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500
hdc shell uinput -T -m 660 1900 660 500
Q6:MD3Colors.primary 是 undefined?
MD3Colors 是调色板刻度集合(primary0 / primary10 / … / neutral0 这类),
语义色 primary 在 DefaultTheme.colors.primary 上:
import {DefaultTheme, MD3Colors} from 'react-native-paper';
DefaultTheme.colors.primary; // 'rgba(103, 80, 164, 1)'
MD3Colors.primary10; // 某个紫
Q7:Button 的 typeof 是 object,正常吗?
正常 —— 它是 forwardRef 的结果。用 typeof x === 'function' 判断组件会误判。
Provider / Chip / Dialog 是普通函数组件(function),Button / Card / FAB / TextInput 是 object。
Q8:需要 --ignore-scripts 吗?
paper 自己的 scripts.prepare 是空的,所以不强制;但为了与其它库统一,我仍然带着它。
小结
react-native-paper 是一整套 Material Design 3 组件库(主入口 57 个导出),
代码很干净(老写法九项全空、ViewPropTypes/Text.propTypes 都不用),
但它依赖两个"带资源"的库(react-native-safe-area-context 要窗口 inset、@expo/vector-icons 要字体)
—— 这两个用纯 JS 桩隔离后,paper 本体在鸿蒙上跑得通 ✓
最值得记下来的是这几条:
-
★★★★★ 两个桩的写法可以直接复用。
useSafeAreaInsets()必须返回对象(调用方解构),把top填成真机实测的 39vp 最接近真实;- 图标桩要提供
glyphMap(用Proxy兜任意键),并且渲一个可见的小方块而不是null——
这样图标的尺寸/位置也能在布局 dump 里被看到 ✓
-
★★★★★
00308018+libjsi.soFAILED 的真正修法是"清.hvigor+entry/.cxx全量重编"。
判断依据:bundle exit=0(JS 没问题)+ 错在BuildNativeWithNinja⇒ 是 CMake/Ninja 缓存损坏。
代价是 16 分 51 秒(全量重编)vs 平时 3~4 分钟(增量)✓ -
★★★★★
10106102/screen is locked是"设备锁屏",不是"App 崩了"。
我差点因此得出"paper 跑不起来"的错误结论 ——
"启动失败 + 判据全无输出 + 截图不像我的页面"这三件事同时出现时,先查启动命令的返回值 ✓ -
★★★★★ 这一轮"只断言存在、不猜
typeof"的策略是对的。
实测Button/Card/FAB/TextInput都是object(forwardRef),
如果我按惯性写"是 function",就会凭空多出 4 条 FAIL ✓
形态事实先NOTE打出来,稳定了再断言。 -
★★★★ 主题系统是完整可用的:
useTheme()返回 7 个顶层键、colors33 键、
primary = rgba(103, 80, 164, 1)(MD3 默认紫)✓ -
★★★ 组件文本的真实坐标是最硬的渲染证据:
Button在x=504 y=1293、Card.Content在x=108 y=1903,且y递增顺序与书写顺序一致 ✓ -
★★★ 我犯的一个接线 bug 值得记:PowerShell 的嵌套数组会被展平。
@(@('a','b'))里的$pair[0]取到的是字符'a'[0],于是package.json被写进了垃圾依赖"r":"f"
⇒npm install报notarget No matching version found for f@i。
修法:配对的字面量用两个变量;写完package.json立刻回读校验。 -
★★
MD3Colors与DefaultTheme.colors是两层东西(前者是刻度primary0/primary10/…,后者才有primary)。
本篇用到的库
| 项 | 内容 |
|---|---|
| 三方库 | react-native-paper(上游 5.15.3 的鸿蒙适配版) |
| 适配仓库 | https://atomgit.com/oh-react-native/react-native-paper |
| 适配 TAG | 5.15.3-ohos-1.0.0 |
| 需要 HAR / 权限 / ohpm | 都不需要(纯 JS) |
| 库类型 | Material Design 3 组件库(57 个导出) |
| 运行时依赖 | ⚠️ 3 个必须显式装:color / @callstack/react-theme-provider / use-latest-callback |
| peerDependencies | ⚠️ react-native-safe-area-context(27 处使用) |
| 图标依赖 | ⚠️ @expo/vector-icons 的 MaterialCommunityIcons(27 处) |
| 导出形态 | 默认无;具名 57 个;组件多为 forwardRef(typeof 为 object) |
| 许可证 | MIT |
| 上游仓库 | https://github.com/callstack/react-native-paper |
| 宿主工程 | RNOH084Demo(测试页 rnAppKey = PaperTestApp) |
npm install "git+https://atomgit.com/oh-react-native/react-native-paper.git#5.15.3-ohos-1.0.0" --ignore-scripts
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4
import {Provider, Button, Card, Chip, FAB, TextInput, DefaultTheme, useTheme} from 'react-native-paper';
// ① 必须用 Provider 包住(否则 useTheme 拿不到主题)
<Provider>
<Button mode="contained" icon="check" onPress={() => {}}>确定</Button>
<Card>
<Card.Title title="标题" subtitle="副标题" />
<Card.Content><Text>内容</Text></Card.Content>
</Card>
<Chip icon="information" onPress={() => {}}>标签</Chip>
<TextInput label="输入" mode="outlined" />
<FAB icon="plus" label="新建" onPress={() => {}} />
</Provider>
// ② 主题(实测可用)
const theme = useTheme(); // {dark:false, roundness, version, isV3, colors(33键), fonts, animation}
theme.colors.primary; // 'rgba(103, 80, 164, 1)' ← MD3 默认紫
DefaultTheme.colors.primary; // 同上
// ⚠️ 3 个运行时依赖必须显式装(file: 接入不自动装)
// ⚠️ safe-area-context 与 @expo/vector-icons 需要装或写桩(桩要给 glyphMap)
// ⚠️ 组件大多是 forwardRef ⇒ typeof 是 'object',别用 typeof === 'function' 判断
// ⚠️ MD3Colors 是刻度集合(primary0/primary10…),语义色在 DefaultTheme.colors 上
// ⚠️ 构建报 00308018 + libjsi.so ⇒ 清 .hvigor 与 entry/.cxx 全量重编(约 17 分钟)
// ⚠️ aa start 报 10106102 ⇒ 设备锁屏,先 power-shell wakeup + uinput 上滑解锁
# 换页启动测试页 —— force-stop 不能省
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey PaperTestApp
# 若报 10106102(锁屏):
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500
判据的复现方式
# ① 导出契约 + 主题
hdc shell "hilog -x | grep ppr-test" | Select-String 'PASS|FAIL|SUMMARY|NOTE'
# ⇒ 导出总数 57;20 个关键导出全在;useTheme().colors.primary = rgba(103,80,164,1)
# ② 组件真实坐标(最硬的渲染证据)
devecocli ui layout | Select-String 'PAPER 描边按钮|这是 Card 的内容区'
# ⇒ w=312 h=60 x=504 y=1293 / w=1104 h=42 x=108 y=1903
验证环境
| 项 | 版本 |
|---|---|
| React Native | 0.84.1 |
| React | 19.2.3 |
| RNOH(npm / ohpm) | @react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3 |
| Node.js / npm | v24.14.0 / 11.9.0 |
| DevEco Studio | 26.0.0.621 |
| HarmonyOS SDK | API 26(26.0.0.32) |
| 设备 | HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64),1320×2232,density 3 |
| 本机状态栏高度 | 117px = 39vp(safe-area 桩里按这个值填 top) |
| 宿主依赖 | ⚠️ 补装 paper 的 3 个运行时依赖 + 2 个纯 JS 桩 |
| 宿主 HAP 产物 | entry-default-signed.hap |
| 本次构建 | 首次失败(00308018 / libjsi.so)⇒ 清 .hvigor + entry/.cxx 全量重编 ⇒ BUILD SUCCESSFUL(16 分 51 秒) |
| 验证规模 | 导出 57 项、20 个关键导出全在;主题实测可用(colors 33 键、primary 为 MD3 紫);Button/Card 文本拿到真实坐标;1 条 FAIL(MD3Colors.primary 我猜错);LogBox 无通知;4 张截图互异 |
⚠️ 基线说明:交付包
spec.json声明RN 0.88.0 + RNOH 0.84.4(两字段自相矛盾),本次验证在RN 0.84.1 + RNOH 0.84.3上完成。
Platform.OS有 171 处分支,实测运行路径未踩到会崩的分支;换基线建议重跑。
相关社区与项目地址
| 项目 | 地址 |
|---|---|
| React Native 鸿蒙官方社区(CPF-RN) | https://atomgit.com/CPF-RN |
| RNOH 框架仓库 | https://atomgit.com/openharmony-RN/ohos_react_native |
| RNOH 三方库使用文档 | https://atomgit.com/OpenHarmony-RN/usage-docs |
| React Native for OpenHarmony 组织 | https://atomgit.com/oh-react-native |
| RN 三方库鸿蒙适配清单 | https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview |
欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN
React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native
RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview
更多推荐



所有评论(0)