已开启
doc: 修改react-native-pdf中英文文档 #59
caolang创建于 7月27日
doc: 修改react-native-pdf中英文文档 #59
已开启
共 2 个文件变更+700-7
| @@ -1,13 +1,353 @@ | |||
| 1 | -# @react-native-ohos/react-native-pdf | 1 | +> 模板版本:v0.4.1 |
| 2 | 2 | ||
| 3 | -This project is based on [react-native-pdf](https://github.com/wonday/react-native-pdf)@7.0.0 | 3 | +<p align="center"> |
| 4 | + <h1 align="center"> <code>react-native-pdf</code> </h1> | ||
| 5 | +</p> | ||
| 4 | 6 | ||
| 5 | -## Documentation | 7 | +本项目基于 [react-native-pdf](https://github.com/wonday/react-native-pdf) 开发。 |
| 6 | 8 | ||
| 7 | -- [中文](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-pdf.md) | 9 | +该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:`@react-native-ohos/react-native-pdf` 版本所属关系如下: |
| 8 | 10 | ||
| 9 | -- [English](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/en/react-native-pdf.md) | 11 | +| 三方库名称 | 三方库版本 | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | npm地址 | |
| 12 | +| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | | ||
| 13 | +| @react-native-ohos/react-native-pdf | ~6.7.5 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-pdf/releases) | 0.72.* | 是 | API12+ | 6.7.4 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-pdf) | | ||
| 10 | 14 | ||
| 11 | -## License | 15 | +## 简介 |
| 12 | 16 | ||
| 13 | -This library is licensed under [The MIT License](https://github.com/wonday/react-native-pdf/blob/master/LICENSE) | 17 | +`react-native-pdf` 是一个 React Native 组件,用于在移动应用中渲染和展示 PDF 文档。该组件封装了原生 PDF 渲染能力,提供丰富的配置选项和事件回调。 |
| 18 | + | ||
| 19 | +## 下载安装 | ||
| 20 | + | ||
| 21 | +进入到工程目录并输入以下命令: | ||
| 22 | + | ||
| 23 | +<!-- tabs:start --> | ||
| 24 | + | ||
| 25 | +#### npm | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +npm install @react-native-ohos/react-native-pdf | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +#### yarn | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +yarn add @react-native-ohos/react-native-pdf | ||
| 35 | +``` | ||
| 36 | + | ||
| 37 | +<!-- tabs:end --> | ||
| 38 | + | ||
| 39 | +下面的代码展示了这个库的基本使用场景: | ||
| 40 | + | ||
| 41 | +> [!WARNING] 使用时 import 的库名不变。 | ||
| 42 | + | ||
| 43 | +```tsx | ||
| 44 | +import React from "react"; | ||
| 45 | +import { View, Dimensions, StyleSheet } from "react-native"; | ||
| 46 | +import Pdf from "react-native-pdf"; | ||
| 47 | + | ||
| 48 | +export function PdfExample() { | ||
| 49 | + // const source = { uri: 'https://www-file.huawei.com/minisite/media/annual_report/annual_report_2022_cn.pdf', cache: true }; | ||
| 50 | + const source = require("../assets/test.pdf"); | ||
| 51 | + | ||
| 52 | + return ( | ||
| 53 | + <View style={styles.sectionContainer}> | ||
| 54 | |||
| 55 | + source={source} | ||
| 56 | + onLoadComplete={(numberOfPages, filePath) => { | ||
| 57 | + console.log(`Number of pages: ${numberOfPages}`); | ||
| 58 | + }} | ||
| 59 | + onPageChanged={(page, numberOfPages) => { | ||
| 60 | + console.log(`Current page: ${page}`); | ||
| 61 | + }} | ||
| 62 | + onError={(error) => { | ||
| 63 | + console.log(error); | ||
| 64 | + }} | ||
| 65 | + onPressLink={(uri) => { | ||
| 66 | + console.log(`Link pressed: ${uri}`); | ||
| 67 | + }} | ||
| 68 | + style={styles.pdf} | ||
| 69 | + /> | ||
| 70 | + </View> | ||
| 71 | + ); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +const styles = StyleSheet.create({ | ||
| 75 | + sectionContainer: { | ||
| 76 | + flex: 1, | ||
| 77 | + justifyContent: "flex-start", | ||
| 78 | + alignItems: "center", | ||
| 79 | + }, | ||
| 80 | + pdf: { | ||
| 81 | + flex: 1, | ||
| 82 | + width: Dimensions.get("window").width, | ||
| 83 | + height: Dimensions.get("window").height, | ||
| 84 | + }, | ||
| 85 | +}); | ||
| 86 | +``` | ||
| 87 | + | ||
| 88 | +## Link | ||
| 89 | + | ||
| 90 | +| | 是否支持autolink | RN框架版本 | | ||
| 91 | +|--------------------------------------|-----------------|------------| | ||
| 92 | +| ~6.7.5 | Yes | 0.72 | | ||
| 93 | + | ||
| 94 | +使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md | ||
| 95 | + | ||
| 96 | +如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。 | ||
| 97 | +<details> | ||
| 98 | + <summary>ManualLink: 此步骤为手动配置原生依赖项的指导</summary> | ||
| 99 | + | ||
| 100 | +首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。 | ||
| 101 | + | ||
| 102 | +本库 HarmonyOS 侧实现依赖@react-native-ohos/react-native-blob-util 的原生端代码,如已在 HarmonyOS 工程中引入过该库,则无需再次引入,可跳过本章节步骤,直接使用。 | ||
| 103 | + | ||
| 104 | +如未引入请参照[@react-native-ohos/react-native-blob-util 文档的 Link 章节](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/react-native-blob-util.md#link)进行引入 | ||
| 105 | + | ||
| 106 | +### 1. Overrides RN SDK | ||
| 107 | + | ||
| 108 | +为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。 | ||
| 109 | + | ||
| 110 | +关于该字段的作用请阅读[官方说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#zh-cn_topic_0000001792256137_overrides) | ||
| 111 | + | ||
| 112 | +```json | ||
| 113 | +{ | ||
| 114 | + ... | ||
| 115 | + "overrides": { | ||
| 116 | + "@rnoh/react-native-openharmony" : "./react_native_openharmony" | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | +``` | ||
| 120 | + | ||
| 121 | +### 2. 引入原生端代码 | ||
| 122 | + | ||
| 123 | +目前有两种方法: | ||
| 124 | + | ||
| 125 | +- 通过 har 包引入; | ||
| 126 | +- 直接链接源码。 | ||
| 127 | + | ||
| 128 | +方法一:通过 har 包引入(推荐) | ||
| 129 | + | ||
| 130 | +> [!TIP] har 包位于三方库安装路径的 `harmony` 文件夹下。 | ||
| 131 | + | ||
| 132 | +打开 `entry/oh-package.json5`,添加以下依赖 | ||
| 133 | + | ||
| 134 | +```json | ||
| 135 | +"dependencies": { | ||
| 136 | + "@rnoh/react-native-openharmony": "file:../react_native_openharmony", | ||
| 137 | + "@react-native-ohos/react-native-pdf": "file:../../node_modules/@react-native-ohos/react-native-pdf/harmony/pdfview.har" | ||
| 138 | + } | ||
| 139 | +``` | ||
| 140 | + | ||
| 141 | +点击右上角的 `sync` 按钮 | ||
| 142 | + | ||
| 143 | +或者在命令行终端执行: | ||
| 144 | + | ||
| 145 | +```bash | ||
| 146 | +cd entry | ||
| 147 | +ohpm install | ||
| 148 | +``` | ||
| 149 | + | ||
| 150 | +方法二:直接链接源码 | ||
| 151 | + | ||
| 152 | +> [!TIP] 如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md) | ||
| 153 | + | ||
| 154 | +### 3. 配置 CMakeLists 和引入 PdfViewPackage | ||
| 155 | + | ||
| 156 | +> 若使用的是 <= 6.7.4-0.3.6 版本,请跳过本章。 | ||
| 157 | + | ||
| 158 | +打开 `entry/src/main/cpp/CMakeLists.txt`,添加: | ||
| 159 | + | ||
| 160 | +```diff | ||
| 161 | +project(rnapp) | ||
| 162 | +cmake_minimum_required(VERSION 3.4.1) | ||
| 163 | +set(CMAKE_SKIP_BUILD_RPATH TRUE) | ||
| 164 | +set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") | ||
| 165 | +set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules") | ||
| 166 | ++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") | ||
| 167 | +set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp") | ||
| 168 | +set(LOG_VERBOSITY_LEVEL 1) | ||
| 169 | +set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") | ||
| 170 | +set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie") | ||
| 171 | +set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use | ||
| 172 | +add_compile_definitions(WITH_HITRACE_SYSTRACE) | ||
| 173 | + | ||
| 174 | +add_subdirectory("${RNOH_CPP_DIR}" ./rn) | ||
| 175 | + | ||
| 176 | +# RNOH_BEGIN: manual_package_linking_1 | ||
| 177 | +add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package) | ||
| 178 | ++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-pdf/src/main/cpp" ./pdfview) | ||
| 179 | +# RNOH_END: manual_package_linking_1 | ||
| 180 | + | ||
| 181 | +file(GLOB GENERATED_CPP_FILES "./generated/*.cpp") | ||
| 182 | + | ||
| 183 | +add_library(rnoh_app SHARED | ||
| 184 | + ${GENERATED_CPP_FILES} | ||
| 185 | + "./PackageProvider.cpp" | ||
| 186 | + "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp" | ||
| 187 | +) | ||
| 188 | +target_link_libraries(rnoh_app PUBLIC rnoh) | ||
| 189 | + | ||
| 190 | +# RNOH_BEGIN: manual_package_linking_2 | ||
| 191 | +target_link_libraries(rnoh_app PUBLIC rnoh_sample_package) | ||
| 192 | ++ target_link_libraries(rnoh_app PUBLIC rnoh_pdf_view) | ||
| 193 | +# RNOH_END: manual_package_linking_2 | ||
| 194 | +``` | ||
| 195 | + | ||
| 196 | +打开 `entry/src/main/cpp/PackageProvider.cpp`,添加: | ||
| 197 | + | ||
| 198 | +```diff | ||
| 199 | +#include "RNOH/PackageProvider.h" | ||
| 200 | +#include "SamplePackage.h" | ||
| 201 | ++ #include "PdfViewPackage.h" | ||
| 202 | + | ||
| 203 | +using namespace rnoh; | ||
| 204 | + | ||
| 205 | +std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) { | ||
| 206 | + return { | ||
| 207 | + std::make_shared<SamplePackage>(ctx), | ||
| 208 | ++ std::make_shared<PdfViewPackage>(ctx) | ||
| 209 | + }; | ||
| 210 | +} | ||
| 211 | +``` | ||
| 212 | + | ||
| 213 | +### 4. 在 ArkTs 侧引入 RTNPdfView 组件 | ||
| 214 | + | ||
| 215 | +找到 **function buildCustomRNComponent()**,一般位于 `entry/src/main/ets/pages/index.ets` 或 `entry/src/main/ets/rn/LoadBundle.ets`,添加: | ||
| 216 | + | ||
| 217 | +```diff | ||
| 218 | + ... | ||
| 219 | ++ import { RTNPdfView, PDF_VIEW_TYPE } from '@react-native-ohos/react-native-pdf'; | ||
| 220 | + | ||
| 221 | + @Builder | ||
| 222 | +export function buildCustomRNComponent(ctx: ComponentBuilderContext) { | ||
| 223 | + ... | ||
| 224 | ++ if (ctx.componentName === PDF_VIEW_TYPE) { | ||
| 225 | ++ RTNPdfView({ | ||
| 226 | ++ ctx: ctx.rnComponentContext, | ||
| 227 | ++ tag: ctx.tag, | ||
| 228 | ++ }) | ||
| 229 | ++ } | ||
| 230 | + ... | ||
| 231 | + } | ||
| 232 | + ... | ||
| 233 | + | ||
| 234 | +``` | ||
| 235 | + | ||
| 236 | +> [!TIP] 本库使用了混合方案,需要添加组件名。 | ||
| 237 | + | ||
| 238 | +在`entry/src/main/ets/pages/index.ets` 或 `entry/src/main/ets/rn/LoadBundle.ets` 找到常量 `arkTsComponentNames` 在其数组里添加组件名 | ||
| 239 | + | ||
| 240 | +```diff | ||
| 241 | +const arkTsComponentNames: Array<string> = [ | ||
| 242 | + SampleView.NAME, | ||
| 243 | + GeneratedSampleView.NAME, | ||
| 244 | + PropsDisplayer.NAME, | ||
| 245 | ++ PDF_VIEW_TYPE | ||
| 246 | + ]; | ||
| 247 | +``` | ||
| 248 | + | ||
| 249 | +### 运行 | ||
| 250 | + | ||
| 251 | +点击右上角的 `sync` 按钮 | ||
| 252 | + | ||
| 253 | +或者在命令行终端执行: | ||
| 254 | + | ||
| 255 | +```bash | ||
| 256 | +cd entry | ||
| 257 | +ohpm install | ||
| 258 | +``` | ||
| 259 | + | ||
| 260 | +然后编译、运行即可。 | ||
| 261 | + | ||
| 262 | +</details> | ||
| 263 | + | ||
| 264 | +## 约束与限制 | ||
| 265 | + | ||
| 266 | +### 兼容性 | ||
| 267 | + | ||
| 268 | +本文档内容基于以下版本验证通过: | ||
| 269 | + | ||
| 270 | +1. RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71; | ||
| 271 | + | ||
| 272 | +## 接口说明 | ||
| 273 | + | ||
| 274 | +> [!TIP] "Platform"列表示该属性在原三方库上支持的平台。 | ||
| 275 | + | ||
| 276 | +> [!TIP] "OpenHarmony Support"列为 yes 表示 OpenHarmony平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。 | ||
| 277 | + | ||
| 278 | +### 属性 | ||
| 279 | + | ||
| 280 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 281 | +| --------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | ------------- | ----------------- | | ||
| 282 | +| source | PDF 数据源配置,如 {uri:xxx, cache:false},详情见下文说明 | object | YES | iOS / Android | yes | | ||
| 283 | +| page | 初始页码索引 | number | NO | iOS / Android | yes | | ||
| 284 | +| scale | 显示缩放比例,需满足 minScale<=scale<=maxScale | number | NO | iOS / Android | yes | | ||
| 285 | +| minScale | 最小缩放值 | number | NO | iOS / Android | yes | | ||
| 286 | +| maxScale | 最大缩放值 | number | NO | iOS / Android | yes | | ||
| 287 | +| horizontal | 页面横向滚动,若需监听方向变化可配合 [[react-native-orientation-locker\]](https://github.com/react-native-oh-library/react-native-orientation-locker) | bool | NO | iOS / Android | no | | ||
| 288 | +| showsHorizontalScrollIndicator | 控制 iOS 上横向滚动条指示器的显示与隐藏 | bool | NO | iOS | no | | ||
| 289 | +| showsVerticalScrollIndicator | 控制 iOS 上纵向滚动条指示器的显示与隐藏 | bool | NO | iOS | no | | ||
| 290 | +| fitWidth | 为 true 时内容自适应宽度,且不可与 scale 同时使用 | bool | NO | iOS / Android | yes | | ||
| 291 | +| fitPolicy | 0 表示按宽度适配,1 表示按高度,2 表示同时适配(默认) | number | NO | iOS / Android | yes | | ||
| 292 | +| spacing | 各页之间的间距 | number | NO | iOS / Android | yes | | ||
| 293 | +| password | PDF 密码,错误时会触发 onError 并提示 “Password required or incorrect password.” | string | NO | iOS / Android | yes | | ||
| 294 | +| style | 常规 View 样式,可用于设置边框、间距颜色等 | object | NO | iOS / Android | yes | | ||
| 295 | +| renderActivityIndicator | 加载过程中显示的自定义指示器组件 | (progress) => Component | NO | iOS / Android | yes | | ||
| 296 | +| enableAntialiasing | 在低分辨率屏幕上提升渲染质量(Android 4.4 可能出现问题) | bool | NO | iOS / Android | no | | ||
| 297 | +| enablePaging | 仅在屏幕上显示一页 | bool | NO | iOS / Android | no | | ||
| 298 | +| enableRTL | 以 “page3, page2, page1” 方式反向滚动 | bool | NO | iOS / Android | no | | ||
| 299 | +| enableAnnotationRendering | 启用批注渲染,注意 iOS 仅支持初始设置,不支持实时切换 | bool | NO | iOS | no | | ||
| 300 | +| enableDoubleTapZoom | 启用双击缩放手势 | bool | NO | iOS / Android | no | | ||
| 301 | +| trustAllCerts | 允许连接使用自签名证书的服务器 | bool | NO | iOS / Android | no | | ||
| 302 | +| singlePage | 仅展示第一页,适用于缩略图场景 | bool | NO | iOS / Android | no | | ||
| 303 | +| onLoadProgress | 加载进度回调,返回 0-1 的进度值 | function(percent) | NO | iOS / Android | yes | | ||
| 304 | +| onLoadComplete | PDF 加载完成回调,返回总页数、本地/缓存路径、尺寸以及目录 | function(numberOfPages, path, {width, height}, tableContents) | NO | iOS / Android | partially | | ||
| 305 | +| onPageChanged | 翻页回调,返回当前页及总页数 | function(page,numberOfPages) | NO | iOS / Android | yes | | ||
| 306 | +| onError | 发生错误时的回调 | function(error) | NO | iOS / Android | yes | | ||
| 307 | +| onPageSingleTap | 页面被单击时的回调 | function(page) | NO | iOS / Android | no | | ||
| 308 | +| onScaleChanged | 缩放变化时的回调 | function(scale) | NO | iOS / Android | yes | | ||
| 309 | +| onPressLink | 点击 PDF 内链接时的回调 | function(uri) | NO | iOS / Android | yes | | ||
| 310 | +| scrollEnabled | 启用或禁用滚动 | bool | NO | iOS | no | | ||
| 311 | +| progressContainerStyle | 进度容器的样式,可设置边框或间距颜色 | object | NO | iOS / Android | yes | | ||
| 312 | + | ||
| 313 | +#### Source | ||
| 314 | + | ||
| 315 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 316 | +| ------------- | --------------------------------------------- | ------ | -------- | ------------- | ----------------- | | ||
| 317 | +| uri | 详细说明见下文 | object | YES | iOS / Android | yes | | ||
| 318 | +| cache | 是否使用缓存 | bool | NO | iOS / Android | yes | | ||
| 319 | +| cacheFileName | 缓存 PDF 使用的文件名 | string | NO | iOS / Android | yes | | ||
| 320 | +| expiration | 缓存文件过期秒数(0 表示不过期) | number | NO | iOS / Android | yes | | ||
| 321 | +| method | 当 uri 为 URL 时的请求方法 | string | NO | iOS / Android | no | | ||
| 322 | +| headers | 当 uri 为 URL 时的请求头 | object | NO | iOS / Android | no | | ||
| 323 | + | ||
| 324 | +#### Uri | ||
| 325 | + | ||
| 326 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 327 | +| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- | ------------- | -------- | ------------- | ----------------- | | ||
| 328 | +| {uri:"http://xxx/xxx.pdf"} | 从 URL 加载 PDF | object | NO | iOS / Android | yes | | ||
| 329 | +| {require("./test.pdf")} | 加载与 JS 文件关联的本地资源(无需在 Xcode 中额外添加) | require(path) | NO | iOS | yes | | ||
| 330 | +| {uri:"bundle-assets://path/to/xxx.pdf"} | 从 Android 项目 assets 目录加载 PDF | object | NO | iOS | no | | ||
| 331 | +| {uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."} | 通过 Base64 字符串加载 PDF | object | NO | iOS / Android | yes | | ||
| 332 | +| {uri:"file:///absolute/path/to/xxx.pdf"} | 从本地文件系统加载 PDF | object | NO | iOS / Android | yes | | ||
| 333 | +| {uri:"ms-appx:///xxx.pdf"} | 从 UWP 应用内置资源加载 PDF | object | NO | Windows | no | | ||
| 334 | +| {uri:"content://com.example.blobs/xxxxxxxx-...?offset=0&size=xxx"} | 通过 content URI 加载 PDF | object | NO | iOS | no | | ||
| 335 | +| {uri:"blob:xxxxxxxx-...?offset=0&size=xxx"} | 从 blob URL 加载 PDF | object | NO | Android | no | | ||
| 336 | + | ||
| 337 | +#### 静态方法 | ||
| 338 | + | ||
| 339 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 340 | +| ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------- | ------------- | ----------------- | | ||
| 341 | +| setPage | 设置 PDF 组件当前页。pageNumber 为正整数,若大于总页数则保持原页码不变。 | function(pageNumber) | NO | iOS / Android | yes | | ||
| 342 | + | ||
| 343 | +## 遗留问题 | ||
| 344 | + | ||
| 345 | +- [ ] onLoadComplete 回调函数参数返回目前仅支持 numberOfPages, path参数:[issue#47](https://github.com/react-native-oh-library/react-native-pdf/issues/47) | ||
| 346 | +- [ ] 原库部分接口在 HarmonyOS 中没有对应属性及接口处理相关逻辑: [issue#48](https://github.com/react-native-oh-library/react-native-pdf/issues/48) | ||
| 347 | +- [x] V0.77 部分属性未实现 HarmonyOS 化: [issue#1](https://gitcode.com/openharmony-sig/rntpc_react-native-pdf/issues/1) | ||
全局openharmony-sig链接改为CPF-RN ![]() ![]() | |||
| 348 | + | ||
| 349 | +## 其他 | ||
| 350 | + | ||
| 351 | +## 开源协议 | ||
| 352 | + | ||
| 353 | +本项目基于 [The MIT License (MIT)](https://github.com/wonday/react-native-pdf/blob/master/LICENSE) ,请自由地享受和参与开源。 | ||
| @@ -0,0 +1,353 @@ | |||
| 1 | +> Template version: v0.4.1 | ||
| 2 | + | ||
| 3 | +<p align="center"> | ||
| 4 | + <h1 align="center"> <code>react-native-pdf</code> </h1> | ||
| 5 | +</p> | ||
| 6 | + | ||
| 7 | +This project is based on [react-native-pdf](https://github.com/wonday/react-native-pdf). | ||
| 8 | + | ||
| 9 | +This third-party library has been migrated to Gitcode and is now available for direct download from npm, the new package name is: `@react-native-ohos/react-native-pdf`. The version correspondence details are as follows: | ||
| 10 | + | ||
| 11 | +| Name | Version | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | npm Address | | ||
| 12 | +| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | | ||
| 13 | +| @react-native-ohos/react-native-pdf | ~6.7.5 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-pdf/releases) | 0.72.* | Yes | API12+ | 6.7.4 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-pdf) | | ||
| 14 | + | ||
| 15 | +## Introduction | ||
| 16 | + | ||
| 17 | +`react-native-pdf` is a React Native component for rendering and displaying PDF documents in mobile applications. It wraps native PDF rendering capabilities and provides extensive configuration options and event callbacks. | ||
| 18 | + | ||
| 19 | +## Installation | ||
| 20 | + | ||
| 21 | +Go to the project directory and execute the following instruction: | ||
| 22 | + | ||
| 23 | +<!-- tabs:start --> | ||
| 24 | + | ||
| 25 | +#### npm | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +npm install @react-native-ohos/react-native-pdf | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +#### yarn | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +yarn add @react-native-ohos/react-native-pdf | ||
| 35 | +``` | ||
| 36 | + | ||
| 37 | +<!-- tabs:end --> | ||
| 38 | + | ||
| 39 | +The following code shows the basic use scenario of the repository: | ||
| 40 | + | ||
| 41 | +> [!WARNING] The name of the imported repository remains unchanged. | ||
| 42 | + | ||
| 43 | +```tsx | ||
| 44 | +import React from "react"; | ||
| 45 | +import { View, Dimensions, StyleSheet } from "react-native"; | ||
| 46 | +import Pdf from "react-native-pdf"; | ||
| 47 | + | ||
| 48 | +export function PdfExample() { | ||
| 49 | + // const source = { uri: 'https://www-file.huawei.com/minisite/media/annual_report/annual_report_2022_cn.pdf', cache: true }; | ||
| 50 | + const source = require("../assets/test.pdf"); | ||
| 51 | + | ||
| 52 | + return ( | ||
| 53 | + <View style={styles.sectionContainer}> | ||
| 54 | |||
| 55 | + source={source} | ||
| 56 | + onLoadComplete={(numberOfPages, filePath) => { | ||
| 57 | + console.log(`Number of pages: ${numberOfPages}`); | ||
| 58 | + }} | ||
| 59 | + onPageChanged={(page, numberOfPages) => { | ||
| 60 | + console.log(`Current page: ${page}`); | ||
| 61 | + }} | ||
| 62 | + onError={(error) => { | ||
| 63 | + console.log(error); | ||
| 64 | + }} | ||
| 65 | + onPressLink={(uri) => { | ||
| 66 | + console.log(`Link pressed: ${uri}`); | ||
| 67 | + }} | ||
| 68 | + style={styles.pdf} | ||
| 69 | + /> | ||
| 70 | + </View> | ||
| 71 | + ); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +const styles = StyleSheet.create({ | ||
| 75 | + sectionContainer: { | ||
| 76 | + flex: 1, | ||
| 77 | + justifyContent: "flex-start", | ||
| 78 | + alignItems: "center", | ||
| 79 | + }, | ||
| 80 | + pdf: { | ||
| 81 | + flex: 1, | ||
| 82 | + width: Dimensions.get("window").width, | ||
| 83 | + height: Dimensions.get("window").height, | ||
| 84 | + }, | ||
| 85 | +}); | ||
| 86 | +``` | ||
| 87 | + | ||
| 88 | +## Link | ||
| 89 | + | ||
| 90 | +| | Is supported autolink | Supported RN Version | | ||
| 91 | +|--------------------------------------|-----------------------|----------------------| | ||
| 92 | +| ~6.7.5 | Yes | 0.72 | | ||
| 93 | + | ||
| 94 | +Using AutoLink need to be configured according to this document, Autolink Framework Guide Documentation: https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md | ||
| 95 | + | ||
| 96 | +If the version you use supports Autolink and the project has been connected to Autolink, skip the ManualLink configuration. | ||
| 97 | +<details> | ||
| 98 | + <summary>ManualLink: this step is a guide to manually configure native dependencies.</summary> | ||
| 99 | + | ||
| 100 | +First, use DevEco Studio to open the HarmonyOS project `harmony` in the project directory. | ||
| 101 | + | ||
| 102 | +The HarmonyOS implementation of this library depends on the native code of @react-native-ohos/react-native-blob-util. If you have already integrated this library into your HarmonyOS project, you do not need to integrate it again; you can skip the steps in this section and use it directly. | ||
| 103 | + | ||
| 104 | +If you haven't integrated it yet, please refer to the [Link section of the @react-native-ohos/react-native-blob-util documentation](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/react-native-blob-util.md#link) for integration. | ||
| 105 | + | ||
| 106 | +### 1. Overrides RN SDK | ||
| 107 | + | ||
| 108 | +To ensure the project relies on the same version of the RN SDK, you need to add an `overrides` field in the project's root `oh-package.json5` file, specifying the RN SDK version to be used. The replacement version can be a specific version number, a semver range, or a locally available HAR package or source directory. | ||
| 109 | + | ||
| 110 | +For more information about the purpose of this field, please refer to the [official documentation](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#en-us_topic_0000001792256137_overrides). | ||
| 111 | + | ||
| 112 | +```json | ||
| 113 | +{ | ||
| 114 | + ... | ||
| 115 | + "overrides": { | ||
| 116 | + "@rnoh/react-native-openharmony" : "./react_native_openharmony" | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | +``` | ||
| 120 | + | ||
| 121 | +### 2. Introducing Native Code | ||
| 122 | + | ||
| 123 | +Currently, two methods are available: | ||
| 124 | + | ||
| 125 | +- Use the HAR file. | ||
| 126 | +- Directly link to the source code. | ||
| 127 | + | ||
| 128 | +Method 1 (recommended): Use the HAR file. | ||
| 129 | + | ||
| 130 | +> [!TIP] The HAR file is stored in the `harmony` directory in the installation path of the third-party library. | ||
| 131 | + | ||
| 132 | +Open `entry/oh-package.json5` file and add the following dependencies: | ||
| 133 | + | ||
| 134 | +```json | ||
| 135 | +"dependencies": { | ||
| 136 | + "@rnoh/react-native-openharmony": "file:../react_native_openharmony", | ||
| 137 | + "@react-native-ohos/react-native-pdf": "file:../../node_modules/@react-native-ohos/react-native-pdf/harmony/pdfview.har" | ||
| 138 | + } | ||
| 139 | +``` | ||
| 140 | + | ||
| 141 | +Click the `sync` button in the upper right corner. | ||
| 142 | + | ||
| 143 | +Alternatively, run the following instruction on the terminal: | ||
| 144 | + | ||
| 145 | +```bash | ||
| 146 | +cd entry | ||
| 147 | +ohpm install | ||
| 148 | +``` | ||
| 149 | + | ||
| 150 | +Method 2: Directly link to the source code. | ||
| 151 | + | ||
| 152 | +> [!TIP] For details, see [Directly Linking Source Code](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md). | ||
| 153 | + | ||
| 154 | +### 3. Configuring CMakeLists and Introducing PdfViewPackage | ||
| 155 | + | ||
| 156 | +> If you are using version <= 6.7.4-0.3.6, please skip this chapter. | ||
| 157 | + | ||
| 158 | +Open `entry/src/main/cpp/CMakeLists.txt` and add the following code: | ||
| 159 | + | ||
| 160 | +```diff | ||
| 161 | +project(rnapp) | ||
| 162 | +cmake_minimum_required(VERSION 3.4.1) | ||
| 163 | +set(CMAKE_SKIP_BUILD_RPATH TRUE) | ||
| 164 | +set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") | ||
| 165 | +set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules") | ||
| 166 | ++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") | ||
| 167 | +set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp") | ||
| 168 | +set(LOG_VERBOSITY_LEVEL 1) | ||
| 169 | +set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") | ||
| 170 | +set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie") | ||
| 171 | +set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use | ||
| 172 | +add_compile_definitions(WITH_HITRACE_SYSTRACE) | ||
| 173 | + | ||
| 174 | +add_subdirectory("${RNOH_CPP_DIR}" ./rn) | ||
| 175 | + | ||
| 176 | +# RNOH_BEGIN: manual_package_linking_1 | ||
| 177 | +add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package) | ||
| 178 | ++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-pdf/src/main/cpp" ./pdfview) | ||
| 179 | +# RNOH_END: manual_package_linking_1 | ||
| 180 | + | ||
| 181 | +file(GLOB GENERATED_CPP_FILES "./generated/*.cpp") | ||
| 182 | + | ||
| 183 | +add_library(rnoh_app SHARED | ||
| 184 | + ${GENERATED_CPP_FILES} | ||
| 185 | + "./PackageProvider.cpp" | ||
| 186 | + "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp" | ||
| 187 | +) | ||
| 188 | +target_link_libraries(rnoh_app PUBLIC rnoh) | ||
| 189 | + | ||
| 190 | +# RNOH_BEGIN: manual_package_linking_2 | ||
| 191 | +target_link_libraries(rnoh_app PUBLIC rnoh_sample_package) | ||
| 192 | ++ target_link_libraries(rnoh_app PUBLIC rnoh_pdf_view) | ||
| 193 | +# RNOH_END: manual_package_linking_2 | ||
| 194 | +``` | ||
| 195 | + | ||
| 196 | +Open `entry/src/main/cpp/PackageProvider.cpp` and add the following code: | ||
| 197 | + | ||
| 198 | +```diff | ||
| 199 | +#include "RNOH/PackageProvider.h" | ||
| 200 | +#include "SamplePackage.h" | ||
| 201 | ++ #include "PdfViewPackage.h" | ||
| 202 | + | ||
| 203 | +using namespace rnoh; | ||
| 204 | + | ||
| 205 | +std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) { | ||
| 206 | + return { | ||
| 207 | + std::make_shared<SamplePackage>(ctx), | ||
| 208 | ++ std::make_shared<PdfViewPackage>(ctx) | ||
| 209 | + }; | ||
| 210 | +} | ||
| 211 | +``` | ||
| 212 | + | ||
| 213 | +### 4. Introducing RTNPdfView Component to ArkTS | ||
| 214 | + | ||
| 215 | +Find `function buildCustomRNComponent()`, which is usually located in `entry/src/main/ets/pages/index.ets` or `entry/src/main/ets/rn/LoadBundle.ets`, and add the following code: | ||
| 216 | + | ||
| 217 | +```diff | ||
| 218 | + ... | ||
| 219 | ++ import { RTNPdfView, PDF_VIEW_TYPE } from '@react-native-ohos/react-native-pdf'; | ||
| 220 | + | ||
| 221 | + @Builder | ||
| 222 | +export function buildCustomRNComponent(ctx: ComponentBuilderContext) { | ||
| 223 | + ... | ||
| 224 | ++ if (ctx.componentName === PDF_VIEW_TYPE) { | ||
| 225 | ++ RTNPdfView({ | ||
| 226 | ++ ctx: ctx.rnComponentContext, | ||
| 227 | ++ tag: ctx.tag, | ||
| 228 | ++ }) | ||
| 229 | ++ } | ||
| 230 | + ... | ||
| 231 | + } | ||
| 232 | + ... | ||
| 233 | + | ||
| 234 | +``` | ||
| 235 | + | ||
| 236 | +> [!TIP] If the repository uses a mixed solution, the component name needs to be added. | ||
| 237 | + | ||
| 238 | +Find the constant `arkTsComponentNames` in `entry/src/main/ets/pages/index.ets` or `entry/src/main/ets/rn/LoadBundle.ets` and add the component name to the array. | ||
| 239 | + | ||
| 240 | +```diff | ||
| 241 | +const arkTsComponentNames: Array<string> = [ | ||
| 242 | + SampleView.NAME, | ||
| 243 | + GeneratedSampleView.NAME, | ||
| 244 | + PropsDisplayer.NAME, | ||
| 245 | ++ PDF_VIEW_TYPE | ||
| 246 | + ]; | ||
| 247 | +``` | ||
| 248 | + | ||
| 249 | +### Running | ||
| 250 | + | ||
| 251 | +Click the `sync` button in the upper right corner. | ||
| 252 | + | ||
| 253 | +Alternatively, run the following instruction on the terminal: | ||
| 254 | + | ||
| 255 | +```bash | ||
| 256 | +cd entry | ||
| 257 | +ohpm install | ||
| 258 | +``` | ||
| 259 | + | ||
| 260 | +Then build and run the code. | ||
| 261 | + | ||
| 262 | +</details> | ||
| 263 | + | ||
| 264 | +## Constraints | ||
| 265 | + | ||
| 266 | +### Compatibility | ||
| 267 | + | ||
| 268 | +This document is verified based on the following versions: | ||
| 269 | + | ||
| 270 | +1. RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71; | ||
| 271 | + | ||
| 272 | +## Available APIs | ||
| 273 | + | ||
| 274 | +> [!TIP] The **Platform** column indicates the platform where the properties are supported in the original third-party library. | ||
| 275 | + | ||
| 276 | +> [!TIP] If the value of **HarmonyOS Support** is **yes**, it means that the OpenHarmony platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android. | ||
| 277 | + | ||
| 278 | +### Properties | ||
| 279 | + | ||
| 280 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 281 | +|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------- | -------- | ------------- |-------------------| | ||
| 282 | +| source | PDF source like {uri:xxx, cache:false}. see the following for detail. | object | YES | iOS / Android | yes | | ||
| 283 | +| page | initial page index | number | NO | iOS / Android | yes | | ||
| 284 | +| scale | should minScale<=scale<=maxScale | number | NO | iOS / Android | yes | | ||
| 285 | +| minScale | min scale | number | NO | iOS / Android | yes | | ||
| 286 | +| maxScale | max scale | number | NO | iOS / Android | yes | | ||
| 287 | +| horizontal | draw page direction, if you want to listen the orientation change, you can use [[react-native-orientation-locker\]](https://github.com/react-native-oh-library/react-native-orientation-locker) | bool | NO | iOS / Android | no | | ||
| 288 | +| showsHorizontalScrollIndicator | shows or hides the horizontal scroll bar indicator on iOS | bool | NO | iOS | no | | ||
| 289 | +| showsVerticalScrollIndicator | shows or hides the vertical scroll bar indicator on iOS | bool | NO | iOS | no | | ||
| 290 | +| fitWidth | if true fit the width of view, can not use fitWidth=true together with scale | bool | NO | iOS / Android | yes | | ||
| 291 | +| fitPolicy | 0:fit width, 1:fit height, 2:fit both(default) | number | NO | iOS / Android | yes | | ||
| 292 | +| spacing | the breaker size between pages | number | NO | iOS / Android | yes | | ||
| 293 | +| password | pdf password, if password error, will call OnError() with message "Password required or incorrect password." | string | NO | iOS / Android | yes | | ||
| 294 | +| style | support normal view style, you can use this to set border/spacing color... | object | NO | iOS / Android | yes | | ||
| 295 | +| renderActivityIndicator | when loading show it as an indicator, you can use your component | (progress) => Component | NO | iOS / Android | yes | | ||
| 296 | +| enableAntialiasing | improve rendering a little bit on low-res screens, but maybe course some problem on Android 4.4, so add a switch | bool | NO | iOS / Android | no | | ||
| 297 | +| enablePaging | only show one page in screen | bool | NO | iOS / Android | no | | ||
| 298 | +| enableRTL | scroll page as "page3, page2, page1" | bool | NO | iOS / Android | no | | ||
| 299 | +| enableAnnotationRendering | enable rendering annotation, notice:iOS only support initial setting,not support realtime changing | bool | NO | iOS | no | | ||
| 300 | +| enableDoubleTapZoom | Enable double tap to zoom gesture | bool | NO | iOS / Android | no | | ||
| 301 | +| trustAllCerts | Allow connections to servers with self-signed certification | bool | NO | iOS / Android | no | | ||
| 302 | +| singlePage | Only show first page, useful for thumbnail views | bool | NO | iOS / Android | no | | ||
| 303 | +| onLoadProgress | callback when loading, return loading progress (0-1) | function(percent) | NO | iOS / Android | yes | | ||
| 304 | +| onLoadComplete | callback when pdf load completed, return total page count, pdf local/cache path, {width,height} and table of contents | function(numberOfPages, path, {width, height}, tableContents) | NO | iOS / Android | partially | | ||
| 305 | +| onPageChanged | callback when page changed ,return current page and total page count | function(page,numberOfPages) | NO | iOS / Android | yes | | ||
| 306 | +| onError | callback when error happened | function(error) | NO | iOS / Android | yes | | ||
| 307 | +| onPageSingleTap | callback when page was single tapped | function(page) | NO | iOS / Android | no | | ||
| 308 | +| onScaleChanged | callback when scale page | function(scale) | NO | iOS / Android | yes | | ||
| 309 | +| onPressLink | callback when link tapped | function(uri) | NO | iOS / Android | yes | | ||
| 310 | +| scrollEnabled | enable or disable scrolling | bool | NO | iOS | no | | ||
| 311 | +| progressContainerStyle | support normal view style, you can use this to set border/spacing color | object | NO | iOS / Android | yes | | ||
| 312 | + | ||
| 313 | +#### Source | ||
| 314 | + | ||
| 315 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 316 | +| ------------- | --------------------------------------------- | ------ | -------- | ------------- | ----------------- | | ||
| 317 | +| uri | see the following for detail. | object | YES | iOS / Android | yes | | ||
| 318 | +| cache | use cache or not | bool | NO | iOS / Android | yes | | ||
| 319 | +| cacheFileName | specific file name for cached pdf file | string | NO | iOS / Android | yes | | ||
| 320 | +| expiration | cache file expired seconds (0 is not expired) | number | NO | iOS / Android | yes | | ||
| 321 | +| method | request method when uri is a url | string | NO | iOS / Android | no | | ||
| 322 | +| headers | request headers when uri is a url | object | NO | iOS / Android | no | | ||
| 323 | + | ||
| 324 | +#### Uri | ||
| 325 | + | ||
| 326 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 327 | +| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- | ------------- | -------- | ------------- | ----------------- | | ||
| 328 | +| {uri:"http://xxx/xxx.pdf"} | load pdf from a url | object | NO | iOS / Android | yes | | ||
| 329 | +| {require("./test.pdf")} | load pdf relate to js file (do not need add by xcode) | require(path) | NO | iOS | yes | | ||
| 330 | +| {uri:"bundle-assets://path/to/xxx.pdf"} | load pdf from assets, the file should be at Android/app/src/main/assets/path/to/xxx.pdf | object | NO | iOS | no | | ||
| 331 | +| {uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."} | load pdf from base64 string | object | NO | iOS / Android | yes | | ||
| 332 | +| {uri:"file:///absolute/path/to/xxx.pdf"} | load pdf from local file system | object | NO | iOS / Android | yes | | ||
| 333 | +| {uri:"ms-appx:///xxx.pdf"} | load pdf bundled with UWP app | object | NO | Windows | no | | ||
| 334 | +| {uri:"content://com.example.blobs/xxxxxxxx-...?offset=0&size=xxx"} | load pdf from content URI | object | NO | iOS | no | | ||
| 335 | +| {uri:"blob:xxxxxxxx-...?offset=0&size=xxx"} | load pdf from blob URL | object | NO | Android | no | | ||
| 336 | + | ||
| 337 | +#### Static Methods | ||
| 338 | + | ||
| 339 | +| Name | Description | Type | Required | Platform | HarmonyOS Support | | ||
| 340 | +| ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------- | ------------- | ----------------- | | ||
| 341 | +| setPage | Set the current page of the PDF component. pageNumber is a positive integer. If pageNumber > numberOfPages, current page is not changed. | function(pageNumber) | NO | iOS / Android | yes | | ||
| 342 | + | ||
| 343 | +## Known Issues | ||
| 344 | + | ||
| 345 | +- [ ] The onLoadComplete callback function parameters currently only support `numberOfPages` and `path`: [issue#47](https://github.com/react-native-oh-library/react-native-pdf/issues/47) | ||
| 346 | +- [ ] Some interfaces of the original library do not have corresponding attributes or interface processing logic in HarmonyOS: [issue#48](https://github.com/react-native-oh-library/react-native-pdf/issues/48) | ||
| 347 | +- [x] Some properties in V0.77 have not yet been implemented for HarmonyOS: [issue#1](https://gitcode.com/openharmony-sig/rntpc_react-native-pdf/issues/1) | ||
| 348 | + | ||
| 349 | +## Others | ||
| 350 | + | ||
| 351 | +## License | ||
| 352 | + | ||
| 353 | +This project is licensed under [The MIT License (MIT)](https://github.com/wonday/react-native-pdf/blob/master/LICENSE). | ||


72版本顶部表格需要把github @react-native-oh-tpl 也写上, 同时给版本号添加链接。(Link部分不需要)