基于 react-native-modal 的 OpenHarmony 适配版,增强型模态弹窗组件(支持滑动手势关闭、动画定制)
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 1 个月前 | ||
| 6 年前 | ||
| 6 年前 | ||
| 6 年前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 5 年前 | ||
| 2 个月前 | ||
| 6 年前 | ||
| 2 个月前 | ||
| 9 年前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 27 天前 | ||
| 27 天前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 2 个月前 |
文档模板:v0.4.2
react-native-modal
本项目基于 react-native-modal 开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-modal 版本所属关系如下:
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
|---|---|---|---|---|---|---|---|
| @react-native-ohos/react-native-modal | ~ 13.0.2 | Gitcode Releases | 0.72.* | 否 | API12+ | 13.0.1 | br_rnoh0.72 |
| @react-native-oh-tpl/react-native-modal | ~ 13.0.1-0.0.1@deprecated | Gitcode Releases | 0.72.* | 否 | API12+ | 13.0.1 | sig |
简介
react-native-modal 是基于 RN 原生 Modal 封装的增强模态框组件,提供丰富进出动画、手势侧滑关闭、遮罩自定义、滚动适配等扩展能力,API 简洁且兼容多端。
下载安装
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/react-native-modal
yarn
yarn add @react-native-ohos/react-native-modal
Link
| 是否支持autolink | RN框架版本 | |
|---|---|---|
| ~13.0.2 | No | 0.72 |
| ~13.0.1-0.0.1@deprecated | No | 0.72 |
约束与限制
兼容性
本文档内容基于以下版本验证通过:
- RNOH: 0.72.96; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
- RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71;
使用示例
下面的代码展示了这个库的基本使用场景:
使用时 import 的库名不变。
import React, {Component} from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';
import Modal from 'react-native-modal';
type Props = {
onPress: () => any;
};
type State<P> = P & {
visible: boolean;
};
const DefaultModalContent: React.FC<Props> = props => (
<View style={styles.content}>
<Text style={styles.contentTitle}>Hi 👋!</Text>
<Button testID={'close-button'} onPress={props.onPress} title="Close" />
</View>
);
abstract class ModalBaseScene<P extends object = {}> extends Component<
any,
State<P>
> {
abstract renderModal(): React.ReactElement<any>;
// @ts-ignore
constructor(props, state?: P) {
super(props);
// @ts-ignore
this.state = {
...state,
visible: false,
};
}
open = () => this.setState({visible: true} as any);
close = () => this.setState({visible: false} as any);
isVisible = () => this.state.visible;
public renderButton(): React.ReactElement<any> {
return (
<Button testID={'modal-open-button'} onPress={this.open} title="Open" />
);
}
render() {
return (
<View style={styles.view}>
{this.renderButton()}
{this.renderModal()}
</View>
);
}
}
class DefaultModal extends ModalBaseScene {
renderModal(): React.ReactElement<any> {
return (
<Modal testID={'modal'} isVisible={this.isVisible()}>
<DefaultModalContent onPress={this.close} />
</Modal>
);
}
}
const styles = StyleSheet.create({
view: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
content: {
backgroundColor: 'white',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 4,
borderColor: 'rgba(0, 0, 0, 0.1)',
},
contentTitle: {
fontSize: 20,
marginBottom: 12,
},
});
export default DefaultModal;
接口说明
"Platform"列表示该属性在原三方库上支持的平台。
"OpenHarmony Support"列为 yes 表示 OpenHarmony平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
组件
| 名称 | 参数类型 | 必填 | 平台 | OpenHarmony平台支持 | 描述 |
|---|---|---|---|---|---|
| Modal | / | yes | all | yes | Modal组件 |
属性
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|
| animationIn | string or object |
"slideInUp" | no | all | yes | 弹窗显示动画 |
| animationInTiming | number |
300 | no | all | yes | 弹窗显示动画时长(毫秒) |
| animationOut | string or object |
"slideOutDown" | no | all | yes | 弹窗隐藏动画 |
| animationOutTiming | number |
300 | no | all | yes | 弹窗隐藏动画时长(毫秒) |
| avoidKeyboard | bool |
false | no | all | yes | 键盘弹出时是否自动上移弹窗 |
| coverScreen | bool |
true | no | all | yes | 是否使用原生 Modal 组件覆盖整个屏幕 |
| hasBackdrop | bool |
true | no | all | yes | 渲染遮罩层 |
| backdropColor | string |
"black" | no | all | yes | 遮罩层背景色 |
| backdropOpacity | number |
0.70 | no | all | yes | 弹窗显示时遮罩层的透明度 |
| backdropTransitionInTiming | number |
300 | no | all | yes | 遮罩层显示动画时长(毫秒) |
| backdropTransitionOutTiming | number |
300 | no | all | yes | 遮罩层隐藏动画时长(毫秒) |
| customBackdrop | node |
null | no | all | yes | 自定义遮罩层元素 |
| children | node |
REQUIRED | yes | all | yes | 弹窗内容 |
| deviceHeight | number |
null | no | all | yes | 设备高度(适用于可隐藏导航栏的设备) |
| deviceWidth | number |
null | no | all | yes | 设备宽度(适用于可隐藏导航栏的设备) |
| isVisible | bool |
REQUIRED | yes | all | yes | 是否显示弹窗 |
| onBackButtonPress | func |
() => null | no | Android | yes | 安卓设备按下返回键时触发 |
| onBackdropPress | func |
() => null | no | all | yes | 点击遮罩层时触发 |
| onModalWillHide | func |
() => null | no | all | yes | 弹窗隐藏动画开始前触发 |
| onModalHide | func |
() => null | no | all | yes | 弹窗完全隐藏后触发 |
| onModalWillShow | func |
() => null | no | all | yes | 弹窗显示动画开始前触发 |
| onModalShow | func |
() => null | no | all | yes | 弹窗完全显示后触发 |
| onSwipeStart | func |
() => null | no | all | yes | 滑动操作开始时触发 |
| onSwipeMove | func |
(percentageShown) => null | no | all | yes | 每次滑动事件触发时调用 |
| onSwipeComplete | func |
({ swipingDirection }) => null | no | all | yes | 达到滑动阈值时触发 |
| onSwipeCancel | func |
() => null | no | all | yes | 未达到滑动阈值时触发 |
| panResponderThreshold | number |
4 | no | all | no | 触摸响应器开始识别滑动事件的阈值 |
| scrollOffset | number |
0 | no | all | no | 大于 0 时禁用滑动关闭功能,用于实现可滚动内容 |
| scrollOffsetMax | number |
0 | no | all | yes | 用于实现内容可滚动时的越界滚动效果 |
| scrollTo | func |
null | no | all | yes | 用于实现可滚动弹窗 |
| scrollHorizontal | bool |
false | no | all | yes | 滚动视图为横向滚动时设为 true(保证滚动逻辑正常) |
| swipeThreshold | number |
100 | no | all | yes | 触发滑动完成回调的滑动阈值 |
| swipeDirection | string or array |
null | no | all | yes | 定义弹窗可滑动的方向,支持 up/down/left/right 单个值或数组组合 |
| useNativeDriver | bool |
false | no | all | yes | 是否使用原生驱动执行动画 |
| useNativeDriverForBackdrop | bool |
null | no | all | yes | 遮罩层动画是否使用原生驱动(避免安卓端闪烁问题) |
| hideModalContentWhileAnimating | bool |
false | no | all | no | 动画完成前隐藏弹窗内容以提升性能 |
| propagateSwipe | bool or func |
false | no | all | no | 允许滑动事件传递给子组件(如弹窗内的滚动视图) |
| style | any |
null | no | all | yes | 应用到弹窗的样式 |
| hardwareAccelerated | bool |
false | no | android | no | 强制为 Modal 独立窗口开启 GPU 硬件加速渲染 |
| statusBarTranslucent | bool |
false | no | android | no | Modal 布局穿透系统状态栏,内容可以绘制到状态栏下方,实现沉浸式全屏弹窗 |
| supportedOrientations | string[] | ['portrait', 'landscape'] | no | ios | no | 单独控制当前 Modal 允许旋转的屏幕方向,不受页面全局方向限制 |
| presentationStyle | 'fullScreen'|'overFullScreen'|'pageSheet'|'formSheet' | fullScreen | no | ios | no | Modal 显示状态 |
| onDismiss | func |
() => void | no | ios | no | Modal 关闭动画完全结束后触发回调 |
| onShow | func |
() => void | no | all | yes | Modal 弹出动画执行完成、弹窗完全显示后触发 |
| onOrientationChange | func |
(orientation) => void | no | all | yes | 弹窗展示期间设备横竖屏切换时触发;弹窗首次渲染也会执行一次,返回当前横竖屏状态 |
API
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| open | function | / | / | no | all | yes | 命令式打开弹窗,需要通过ref调用(modalRef.current.open()) |
| close | function | / | / | no | all | yes | 命令式关闭弹窗,需要通过ref调用(modalRef.current.close()) |
遗留问题
其他
无
目录结构
/rntpc_react-native-modal # 项目根目录
├── src # RN 代码(核心库源码)
│ └─ index.ts # 入口文件,导出 ReactNativeModal
│ └─ modal.tsx # Modal 核心组件实现
│ └─ modal.style.ts # 动画 / 样式相关
│ └─ types.ts # 类型定义(ModalProps、动画、方向等)
│ └─ utils.ts # 工具函数
│ └─ global.d.ts # 全局类型声明
├── dist # 编译产物(发布包入口 dist/index.js)
├── example # 示例 Demo
├── package.json # 包配置,name: @react-native-ohos/react-native-modal
├── tsconfig.json # TS 编译配置
├── buildEnv.sh # 构建环境脚本
├── README.md # 中文安装使用方法
└── README_en.md # 英文安装使用方法
贡献代码
使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。
开源协议
本项目基于 MIT License ,请自由地享受和参与开源。