输入框防键盘遮挡适配库
| Files | Last commit | Last update |
|---|---|---|
| 17 days ago | ||
| 17 days ago | ||
| 18 days ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 27 days ago | ||
| 18 days ago | ||
| 17 days ago | ||
| 17 days ago | ||
| 1 month ago | ||
| 17 days ago | ||
| 1 month ago |
@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,鸿蒙侧 HAR 的 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/react-native-avoid-softinput@5.0.1 --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)
- 在
harmony/entry/src/main/cpp/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 或不同版本。
ArkTS 组件名(Autolinking 与手动接入都需要):AvoidSoftInputView 由本库的 ArkTS 组件渲染,Autolinking 不会修改宿主页面。请在宿主创建 RNApp 的页面(RNOH 工程模板为 harmony/entry/src/main/ets/pages/Index.ets)的 rnInstanceConfig 中加入组件名,否则该组件不渲染(与本仓示例相同):
RNApp({
rnInstanceConfig: {
createRNPackages,
enableCAPIArchitecture: true,
arkTsComponentNames: ['AvoidSoftInputView'],
// ...保留宿主原有配置
},
// ...保留宿主原有参数
})
本库本体不要求额外系统权限。
使用说明
基础避让
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 要求) |
| 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-avoid-softinput.git
cd react-native-avoid-softinput
Windows 下可在克隆时指定短目录名,例如 git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-avoid-softinput.git C:\rasi。
2. 进入 example 目录,安装依赖
cd example
npm install --legacy-peer-deps
Example 从 npm 公仓安装 @hxa-rn/react-native-avoid-softinput@5.0.1,不需要在仓根执行 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:核对
example/node_modules/@hxa-rn/react-native-avoid-softinput/harmony/avoid_softinput.har是否存在;不要将example_auto的 node_modules 当成example的依赖。 - 原生模块或组件未注册:检查 HAR、CMake、C++ 和 ETS 注册,排除重复注册并重建 HAP。
- SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
- Ninja
.rsp创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。
约束与限制
兼容性:
| 项 | 值 |
|---|---|
| 上游基线 | react-native-avoid-softinput@5.0.0 |
| 适配版本 | 5.0.0(与上游基线同号) |
| RN / RNOH | RN 0.72.5 + @react-native-oh/react-native-harmony@0.72.143 |
| 鸿蒙最低兼容 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'](见「集成指南」第 3 步),否则组件无法由 RNOH ArkTS builder 渲染。- Android 专属
windowSoftInputMode相关方法在 HarmonyOS 侧作为兼容门面保留,调用后无害返回,不声明等价系统窗口模式能力。 softInputAppliedOffsetChanged在动画期可能逐帧触发,若在该回调里打印日志或触发重渲染,容易刷屏或造成卡顿,业务侧按需节流。
开源 License
本项目基于 MIT License 开源,与上游协议一致。
问题反馈渠道
使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。