rntpc_react-native-text-size:基于 react-native-text-size 的 OpenHarmony 适配版,精确测量文本尺寸(换行、高度计算)

基于 react-native-text-size 的 OpenHarmony 适配版,精确测量文本尺寸(换行、高度计算)

分支4Tags4
文件最后提交记录最后更新时间
13 天前
13 天前
1 年前
1 年前
7 年前
8 年前
10 个月前
7 年前
4 个月前
13 天前
7 年前
27 天前
27 天前
27 天前
1 个月前
7 年前
7 年前
7 年前
13 天前
1 个月前

文档模板:v0.4.2

react-native-text-size

Supported platforms License

本项目基于 react-native-text-size 开发。

该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-text-size(JS 别名 react-native-text-size),版本所属关系如下:

三方库名称 三方库版本(npm地址) 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 源码地址
@react-native-ohos/react-native-text-size ~ 4.2.0 (开发中) Gitcode Releases 0.84.* / 0.82.* 是 API12+ v4.0.0-rc.1 master
@react-native-ohos/react-native-text-size ~ 4.1.0 Gitcode Releases 0.77.* 否 API12+ v4.0.0-rc.1 br_rnoh0.77
@react-native-ohos/react-native-text-size ~ 4.0.1 Gitcode Releases 0.72.* 是 API12+ v4.0.0-rc.1 br_rnoh0.72
@react-native-oh-tpl/react-native-text-size <= 4.0.0-0.0.11@deprecated Github Releases(deprecated) 0.72.* 否 API12+ v4.0.0-rc.1 sig

简介

react-native-text-size 提供在文本布局渲染前精确测量其尺寸(宽度、高度、行数、行信息等)的能力,从而避免二次渲染、提升长列表与自适应布局的性能。

本库为其提供 React Native 鸿蒙(HarmonyOS)适配,基于 TurboModule 实现,支持 measure、flatHeights、fontFromSpecs、specsForTextStyles、fontFamilyNames、fontNamesForFamilyName 等接口。

下载安装

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-text-size

yarn

yarn add @react-native-ohos/react-native-text-size
是否支持autolink RN框架版本
~4.2.0 是 0.82.* / 0.84.*

使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md

如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。

ManualLink: 此步骤为手动配置原生依赖项的指导

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony。

1. Overrides RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "~0.82.30" // 0.82 工程;0.84 工程改为对应 0.84.x 版本
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
  }
}

2. 引入原生端代码

目前有两种方法:

  1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
  2. 直接链接源码。

方法一:通过 har 包引入(推荐)

har 包位于三方库安装路径的 `harmony` 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@rnoh/react-native-openharmony": "file:../react_native_openharmony",
    "@react-native-ohos/react-native-text-size": "file:../../node_modules/@react-native-ohos/react-native-text-size/harmony/text_size.har"
  }

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

方法二:直接链接源码

如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)

3. 配置 CMakeLists 和引入 RNTextSizePackage

若工程已接入 RNOH AutoLink,且本库的 harmony.autolinking 配置生效,则 CMake 与 PackageProvider 注册可由 AutoLink 自动生成,可跳过本节手动配置。

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-text-size/src/main/cpp" ./text_size)
# RNOH_END: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_text_size)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
+ #include "RNTextSizePackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
+     std::make_shared<RNTextSizePackage>(ctx)
    };
}

4. 在 ArkTs 侧引入 RNTextSizePackage

打开 entry/src/main/ets/RNPackagesFactory.ts,或者 entry/src/main/ets/rn/RNPackagesFactory.ts,添加:

  ...
+ import { RNTextSizePackage } from '@react-native-ohos/react-native-text-size/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
+   new RNTextSizePackage(ctx)
  ];
}

运行

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和手机 ROM。

本文档内容基于以下版本验证通过:

  1. RNOH: 0.82.7; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2.636; ROM: 6.0.0.125;
  2. RNOH: 0.84.2; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2.636; ROM: 6.0.0.125;

权限要求

无特殊权限要求。

编译运行API要求(如有)

当前三方库所有版本均已实现版本隔离,支持在 `API12+` 工程编译,及 `API12+` ROM运行。

使用示例

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变,JS 侧通过 `react-native-text-size` 导入。

import React, { useState, useEffect } from 'react';
import { ScrollView, Text, View, Dimensions, TextInput } from 'react-native';
import RTNTextSize, { TSFontSpecs } from 'react-native-text-size';

export default function TextSizeExample() {
  const [width, setWidth] = useState<number>();
  const [height, setHeight] = useState<number>();
  const [text, setText] = useState('I ❤️ react-native-text-size');

  const fontSpecs: TSFontSpecs = { fontSize: 20, fontStyle: 'normal', fontWeight: '700' };

  useEffect(() => {
    (async () => {
      // 测量单段文本的宽高
      const w = Dimensions.get('window').width * 0.8;
      const res = await RTNTextSize.measure({ text, width: w, ...fontSpecs });
      setWidth(res.width);
      setHeight(res.height);
    })();
  }, []);

  return (
    <ScrollView style={{ flexGrow: 1 }}>
      <View style={{ padding: 12 }}>
        <Text>measure 测量文本宽高:</Text>
        <Text style={{ width, height, ...fontSpecs }}>{text}</Text>
        <TextInput
          value={text}
          onChangeText={setText}
          style={{ height: 40, borderWidth: 1, borderColor: '#ccc' }}
        />
      </View>
    </ScrollView>
  );
}

使用说明

measure - 测量单段文本宽高

import RTNTextSize from 'react-native-text-size';

const result = await RTNTextSize.measure({
  text: '要测量的文本,可含 emoji ❤️',
  width: 200,           // 限制最大宽度,默认不限
  fontSize: 16,
  fontWeight: '400',
});
// result: { width, height, lineCount, ... }

flatHeights - 批量测量多段文本高度

const heights = await RTNTextSize.flatHeights({
  text: ['第一段', '第二段', '第三段'],
  width: Dimensions.get('window').width * 0.8,
  fontSize: 14,
});
// heights: number[],与 text 数组一一对应

字体查询

const info    = await RTNTextSize.fontFromSpecs({ fontFamily: 'HarmonyOS Sans SC', fontSize: 20 });
const styles  = await RTNTextSize.specsForTextStyles();  // 系统默认文本样式的字体信息
const families = await RTNTextSize.fontFamilyNames();     // 系统字体族列表
const names    = await RTNTextSize.fontNamesForFamilyName('HarmonyOS Sans SC');

接口说明

"Platform"列表示该属性在原三方库上支持的平台。

"OpenHarmony Support"列为 yes 表示 OpenHarmony平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

API

名称 类型 参数类型 返回值 必填 平台 OpenHarmony平台支持 描述
measure function TSMeasureParams Promise<TSMeasureResult> No All partially 测量文本,返回 { width, height, lineCount };当前不返回 lineInfo(见遗留问题)
flatHeights function TSHeightsParams Promise<number[]> No All partially 测量一组文本的高度,返回值与 text 数组一一对应;宽度约束暂未生效,高度按未换行(单行)计算
specsForTextStyles function / Promise<{ [key: string]: TSFontForStyle }> No All yes 获取系统默认配置的字体的具体信息
fontFromSpecs function TSFontSpecs Promise<TSFontInfo> No All partially 返回从给定规范中获得的字体特征
fontFamilyNames function / Promise<string[]> No All partially 获取系统上可用的字体族名称列表;依赖系统预置字体配置文件,当前设备可能返回空(见遗留问题)
fontNamesForFamilyName function string Promise<string[]> No All partially 返回指定字体族中的字体名称列表;依赖系统预置字体配置文件,当前设备可能返回空(见遗留问题)

属性

TSMeasureParams

名称 参数类型 默认值 必填 平台 OpenHarmony平台支持 描述
text string 无 Yes All yes 要测量的文本,可包含 emoji,不可为 null
width number 屏幕宽度 No All partially 限制文本的最大宽度,未设置时取屏幕宽度;当前仅影响 lineCount/lastLineWidth 的计算,返回的 width/height 按单行测量、不受该约束
allowFontScaling boolean true No All yes 测量结果是否跟随系统字体缩放
usePreciseWidth boolean false No All yes 为 true 时返回值中附带 lastLineWidth(最后一行宽度)
lineInfoForLine number 无 No All no 指定返回第几行(>=0)的行信息

TSHeightsParams

名称 参数类型 默认值 必填 平台 OpenHarmony平台支持 描述
text Array<string | null> 无 Yes All yes 要测量的一组文本,返回的高度数组与其一一对应
width number 屏幕宽度 No All no 限制每段文本的最大宽度
allowFontScaling boolean true No All yes 测量结果是否跟随系统字体缩放

TSFontSpecs

名称 参数类型 默认值 必填 平台 OpenHarmony平台支持 描述
fontFamily string 无(系统默认字体) No All yes 字体族名称
fontSize number 16 No All yes 字体大小
fontStyle TSFontStyle 'normal' No All partially 字体样式:'normal' / 'italic';测量接口暂未传入该参数,仅在 fontFromSpecs 返回值中生效
fontWeight TSFontWeight 'normal' No All yes 字重:'normal' / 'bold' / '100'~'900'
fontVariant Array 无 No iOS no 字体变体
letterSpacing number 0 No iOS, Android yes 字符间距
includeFontPadding boolean true No Android no 是否包含字体上下留白
textBreakStrategy TSTextBreakStrategy 无 No Android yes 文本换行策略:'simple' / 'highQuality' / 'balanced'

遗留问题

其他

  1. specsForTextStyles函数返回值中subheadline属性名称,harmony 端与 ios端表现不一致,harmony端字段名称为subhead。
  2. fontFromSpecs函数返回值中缺少 fontName、capHeight、xHeight、top 字段。

目录结构

/rntpc_react-native-text-size   # 项目根目录
├── harmony                          # 鸿蒙适配代码
│    └─ text_size.har                    # har 包
│    └─ text_size                        # 鸿蒙适配核心代码
│          └─ Index.ets                  # 鸿蒙适配代码入口
│          └─ ts.ets                     # ArkTS 侧类型导出入口
│          └─ src/main
│              └─ ets
│                  └─ RNTextSizePackage.ets       # 鸿蒙侧 Package(TurboModule 注册枢纽)
│                  └─ RNTextSizeTurboModule.ts    # TurboModule 实现
│                  └─ Config.ts / Logger.ets      # 配置与日志
│                  └─ generated/                  # codegen 生成的 ArkTS 代码
│              └─ cpp
│                  └─ CMakeLists.txt             # C++ 侧构建配置(目标 rnoh_text_size)
│                  └─ RNTextSizePackage.h        # C++ Package
│                  └─ RNTextSizeTurboModule.cpp/.h  # TurboModule C++ 桥接
│                  └─ generated/                 # codegen 生成的 C++ 代码
├── src                              # RN 代码
│    └─ index.ts                        # 入口文件
│    └─ NativeTextSize.tsx              # TurboModule Spec 定义(codegen 输入)
├── lib                              # 构建产物(commonjs / module / typescript)
├── example                          # 示例工程
├── README.md                        # 中文文档
├── README_en.md                     # 英文文档

贡献代码

使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。

开源协议

本项目基于 The BSD 2-Clause License(BSD) ,请自由地享受和参与开源。

项目介绍

基于 react-native-text-size 的 OpenHarmony 适配版,精确测量文本尺寸(换行、高度计算)

定制我的领域