@hxa-rn/react-native-avoid-softinput
v1.0.1
Published
Native logic for avoiding covering text inputs by soft input views
Readme
@hxa-rn/react-native-avoid-softinput
react-native-avoid-softinput 基于上游 react-native-avoid-softinput 开发。如果在使用过程中有任何问题,欢迎在GitCode提交Issue,会及时跟进。
项目介绍
react-native-avoid-softinput 为 React Native 应用提供软键盘避让能力:监听软键盘显示、隐藏、高度变化和已施加偏移变化,在输入框可能被遮挡时调整 RN 视图位置或滚动容器余量,并在键盘收起后复位。
@hxa-rn/react-native-avoid-softinput 是 OpenHarmony(RNOH / Fabric 架构)适配版。npm 包名为 @hxa-rn/react-native-avoid-softinput,鸿蒙侧 ohpm 包名仍为 @oh-rn/react-native-avoid-softinput;两者不要混用。包内同时声明 harmony.alias: "react-native-avoid-softinput",便于 RNOH 按上游业务名解析。适配面包括:
- 1 个 TurboModule:
AvoidSoftInput - 15 个 TurboModule 方法
- 1 个 Fabric 组件:
AvoidSoftInputView - 7 个组件 props
- 4 个组件事件
- 4 个 device 事件
- 5 个 hooks
集成指南
本节用于接入已有 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。
1. 安装适配包
安装 npmjs 上的正式版本:
npm install @hxa-rn/[email protected] --save-exact --legacy-peer-deps安装包已包含 JS/类型产物、鸿蒙源码和 harmony/avoid_softinput.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 {AvoidSoftInput, AvoidSoftInputView} from '@hxa-rn/react-native-avoid-softinput';3. 注册鸿蒙原生模块
本包声明了 Autolinking 元数据:CMake 目标 avoid_softinput,ohpm 包 @oh-rn/react-native-avoid-softinput,C++ / ETS 类 AvoidSoftinputPackage。宿主启用 RNOH Autolinking 后,应检查生成的 HAR 依赖、CMake 链接及 C++ / ETS Package 注册是否齐全;已自动注册时不要重复手动注册。
Autolinking 不可用时,保留宿主已有配置,补齐以下四处:
- 在
harmony/entry/oh-package.json5的dependencies追加下项,然后在harmony/entry执行ohpm install并同步工程:
"@oh-rn/react-native-avoid-softinput": "file:../../node_modules/@hxa-rn/react-native-avoid-softinput/harmony/avoid_softinput.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-avoid-softinput/src/main/cpp" ./avoid_softinput)
# 放在 rnoh_app 目标创建之后:
target_link_libraries(rnoh_app PUBLIC avoid_softinput)- 在
PackageProvider.cpp添加头文件,并把实例加入已有getPackages返回集合(本仓库模板可加入ManualLinkingPackage列表):
#include "AvoidSoftinputPackage.h"
// 加入已有 Package 集合:
std::make_shared<rnoh::AvoidSoftinputPackage>(ctx)- 在
harmony/entry/src/main/ets/RNPackagesFactory.ets添加默认导入,并把实例加入已有createRNPackages返回数组:
import AvoidSoftinputPackage from '@oh-rn/react-native-avoid-softinput';
// 加入 createRNPackages(ctx) 返回数组:
new AvoidSoftinputPackage(ctx)确保宿主 RNApp 使用上述 createRNPackages,并启用 enableCAPIArchitecture: true。完成后重新生成宿主 Bundle、构建并安装 HAP;只刷新 JS 不会加载新增的原生模块。若 HAR 内 RNOH 相对依赖无法解析,在宿主鸿蒙根 oh-package.json5 的 overrides 中将 @rnoh/react-native-openharmony 指向宿主正在使用的同一 RNOH HAR,勿混用 debug/release 或不同版本。
本库本体不要求额外系统权限。
使用说明
基础避让
import React from 'react';
import { TextInput } from 'react-native';
import { AvoidSoftInputView } from '@hxa-rn/react-native-avoid-softinput';
export default function FormView() {
return (
<AvoidSoftInputView
style={{ flex: 1 }}
enabled={true}
avoidOffset={40}
easing="easeInOut"
showAnimationDuration={660}
hideAnimationDuration={220}
>
<TextInput />
</AvoidSoftInputView>
);
}事件订阅
import { AvoidSoftInput } from '@hxa-rn/react-native-avoid-softinput';
const subscription = AvoidSoftInput.onSoftInputShown(({ softInputHeight }) => {
console.log(softInputHeight);
});
subscription.remove();接口文档
AvoidSoftInputView props:
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| enabled | boolean | true | 是否启用避让 |
| avoidOffset | number | 0 | 额外避让偏移 |
| easing | 'easeIn' \| 'easeInOut' \| 'easeOut' \| 'linear' | 'linear' | 位移动画缓动 |
| showAnimationDelay | number | 0 | 键盘显示位移动画延迟,单位 ms |
| showAnimationDuration | number | 660 | 键盘显示位移动画时长,单位 ms |
| hideAnimationDelay | number | 0 | 键盘隐藏复位动画延迟,单位 ms |
| hideAnimationDuration | number | 220 | 键盘隐藏复位动画时长,单位 ms |
AvoidSoftInputView 组件事件:
| 事件 | Payload |
|---|---|
| onSoftInputShown | { softInputHeight: number } |
| onSoftInputHidden | { softInputHeight: number } |
| onSoftInputHeightChange | { softInputHeight: number } |
| onSoftInputAppliedOffsetChange | { appliedOffset: number } |
AvoidSoftInput 方法:
| 方法 | 说明 |
|---|---|
| setEnabled(enabled) | 设置模块路径避让启用状态 |
| setAvoidOffset(offset) | 设置模块路径额外偏移 |
| setEasing(easing) | 设置模块路径缓动 |
| setShowAnimationDelay(delay) | 设置键盘显示动画延迟 |
| setShowAnimationDuration(duration) | 设置键盘显示动画时长 |
| setHideAnimationDelay(delay) | 设置键盘隐藏动画延迟 |
| setHideAnimationDuration(duration) | 设置键盘隐藏复位动画时长 |
| setShouldMimicIOSBehavior(value) | Android 专属门面方法,HarmonyOS 侧无害返回 |
| setAdjustNothing() | Android 专属门面方法,HarmonyOS 侧无害返回 |
| setAdjustPan() | Android 专属门面方法,HarmonyOS 侧无害返回 |
| setAdjustResize() | Android 专属门面方法,HarmonyOS 侧无害返回 |
| setAdjustUnspecified() | Android 专属门面方法,HarmonyOS 侧无害返回 |
| setDefaultAppSoftInputMode() | Android 专属门面方法,HarmonyOS 侧无害返回 |
| addListener(eventName) | RN 事件订阅计数接口 |
| removeListeners(count) | RN 事件订阅计数接口 |
Hooks:
useSoftInputShown、useSoftInputHidden、useSoftInputHeightChanged、useSoftInputAppliedOffsetChanged、useSoftInputState。
Device 事件:
softInputShown、softInputHidden、softInputHeightChanged、softInputAppliedOffsetChanged。
快速验证(运行 Example)
前置条件
- Node.js >= 20(以示例 engines 为准),npm,以及 DevEco Studio 配套的 ohpm / SDK。
- 示例版本:React Native
0.72.5、RNOH0.72.143。 - 鸿蒙工程配置:targetSdkVersion=6.1.1(24),compatibleSdkVersion=5.1.0(18)。设备应满足最低版本及本库系统能力要求。
- 在 DevEco Studio 中配置与当前应用包名匹配的签名,不能直接使用其他电脑上的证书路径。
运行步骤
1. 克隆仓库
git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-avoid-softinput.git
cd react-native-avoid-softinput以下步骤使用 example 展示工程;example_auto 的依赖与构建输出独立,不要混用。Windows 建议使用较短目录,避免 RNOH 原生构建中间路径过长。
2. 准备库与示例依赖
进入示例目录安装。package.json 已将本包精确锁定为 npmjs 上的 1.0.1:
cd example
npm install --legacy-peer-deps3. 生成 JS Bundle
npm run dev确认生成 example/harmony/entry/src/main/resources/rawfile/bundle.harmony.js。先解决命令报错,再进入原生构建。
4. 同步与运行鸿蒙工程
用 DevEco Studio 打开 example/harmony,完成依赖同步。缺少 ohpm 依赖时,在该目录使用 DevEco 配套工具执行 ohpm install --all,再同步。保留示例已有的 RNOH HAR 路径和版本。
示例已配置本库运行所需的依赖与接线,无需重复添加 Package。选择设备、配置签名并点击运行,生成并安装 HAP。修改 JS 后重新生成 Bundle;修改原生依赖后重新构建安装 HAP。
常见问题
- 找不到 JS 模块:检查适配包安装、Metro 别名及对应入口,修改 Metro 后重启打包进程。
- 找不到本地包或 HAR:核对当前目录、文件名及准备步骤;不要将
example_auto的 node_modules 当成example的依赖。 - 原生模块或组件未注册:检查 HAR、CMake、C++ 和 ETS 注册,排除重复注册并重建 HAP。
- SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
- Ninja
.rsp创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。
约束与限制
兼容性:
| 项 | 值 |
|---|---|
| 上游基线 | [email protected] |
| 适配版本 | 1.0.1 |
| RN / RNOH | RN 0.72.5 + @react-native-oh/[email protected] |
| 鸿蒙最低兼容 API | API 18(compatibleSdkVersion 5.1.0(18)) |
| 目标 API | API 24(targetSdkVersion 6.1.1(24)) |
| 运行系统 | HarmonyOS |
| 本 npm 版本验证范围 | Node 22 + DevEco Studio 6.1.1 / SDK API 24;example 与 example_auto 编译出 HAP。未以本次 npm 包执行真机功能验证 |
权限:
本库 HAR module.json5 的 requestPermissions 为空数组。本库本体及其三方依赖不声明任何系统权限。
使用约束:
AvoidSoftInputView是 Fabric 组件,不是 PlatformView,也不使用 TextureView。AvoidSoftInputView需要加入arkTsComponentNames: ['AvoidSoftInputView'],否则组件无法由 RNOH ArkTS builder 渲染。- Android 专属
windowSoftInputMode相关方法在 HarmonyOS 侧作为兼容门面保留,调用后无害返回,不声明等价系统窗口模式能力。 softInputAppliedOffsetChanged在动画期可能逐帧触发,日志展示容易被该事件刷屏。验收应以结果面板计数器和结构化读数为准。
开源 License
本项目基于 MIT License 开源,与上游协议一致。
问题反馈渠道
使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。
