本文是「鸿蒙 6.1 API 23 开发坑系列」第 11 篇(非 UI 系第 5 篇)。本篇讲 @ohos.measure namespace(API 9+,鸿蒙 6.1 API 23 基座)—— 文本测量 MeasureText.measureText/MeasureText.measureTextSize static 方法 + MeasureOptions interface + SizeOptions 返回类型。鸿蒙坑根因:① MeasureText.measureText(options) 返回 number(文本单行宽度 px),不是 React measureText 返回 TextMetrics 对象;② MeasureText.measureTextSize(options) 返回 SizeOptionswidth+height),不是 measureText 返回的 number——多行文本测量要用 measureTextSize 不是 measureText;③ MeasureOptions 必填字段 textContent: string | Resource(不是 text 字段),可选 fontSize/fontWeight/fontFamily/letterSpacing/maxWidth/lineHeight/overflow;④ MeasureText.measureText/measureTextSize 废弃迁移到 UIContext.getMeasureUtils() 实例方法(API 18 废弃),新代码必须 getUIContext().getMeasureUtils().measureText(options);⑤ MeasureUtils 实例方法签名跟 MeasureText static 一致(measureText(options: MeasureOptions): number + measureTextSize(options: MeasureOptions): SizeOptions),只是从 static 改实例方法;⑥ MeasureOptions.fontSize 单位是 number(px)或 string(“16fp”)或 Resource,传 number 默认 px 不是 fp(React fontSize 默认 px 一致)。

一、开篇:鸿蒙 measure 不是浏览器 canvas measureText,是「namespace static MeasureText + MeasureOptions」

你写 Web 前端时,文本测量用 canvas.getContext('2d').measureText(text)(返回 TextMetrics 对象,含 width/actualBoundingBoxLeft/actualBoundingBoxRight 等字段):

// Web:canvas measureText 返回 TextMetrics 对象
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')!
ctx.font = '16px sans-serif'  // ✅ 先设 font 再 measureText
const metrics: TextMetrics = ctx.measureText('hello web measure')  // ✅ 返回 TextMetrics 对象
console.info('width: ' + metrics.width)  // ✅ TextMetrics.width 文本宽度 px
console.info('actualBoundingBoxRight: ' + metrics.actualBoundingBoxRight)  // ✅ TextMetrics 实际边界
// Web measureText 返回 TextMetrics 对象(含 width + actualBoundingBox + fontBoundingBox)

你写鸿蒙 ArkTS 时,文本测量用 MeasureText.measureText(options) static 方法(返回 number 文本单行宽度 px,不是 TextMetrics 对象):

// ArkTS MeasureText.measureText:namespace static 方法,返回 number 不是 TextMetrics
import measure from '@ohos.measure'  // ✅ default import(measure 是 namespace)

// ✅ MeasureText.measureText 带 MeasureOptions(textContent 必填,不是 text 字段)
const width: number = measure.MeasureText.measureText({
  textContent: 'hello harmony measure',  // ✅ textContent 必填(不是 text 字段)
  fontSize: '16fp',  // ✅ fontSize 可选(string "16fp" 或 number px)
  fontWeight: FontWeight.Normal  // ✅ fontWeight 可选 enum
})
// ✅ measureText 返回 number(文本单行宽度 px),不是 TextMetrics 对象
console.info('width: ' + width)  // ✅ width 是 number(px)
// 鸿蒙坑根因:measureText 返回 number 不是 TextMetrics,多行用 measureTextSize 返回 SizeOptions

Web vs 鸿蒙 measure 的区别:Web 把文本测量当 canvas.measureText 方法(返回 TextMetrics 对象,含 width + actualBoundingBox + fontBoundingBox 多字段,先设 ctx.font 再测),ArkTS 把文本测量当 MeasureText.measureText static 方法(返回 number 单行宽度 px,不返回 TextMetrics 对象,font 信息全部传 MeasureOptions 字段)。根因不是方法是 static——鸿蒙 MeasureText.measureTextMeasureText class 的 static 方法(API 9~至今),废弃迁移到 UIContext.getMeasureUtils() 实例方法(API 18 废弃),MeasureOptions.textContent 必填(不是 React text 参数),measureTextSize 返回 SizeOptionswidth+height)用于多行文本测量(React measureText 只测单行返回 TextMetrics.width)。

二、根因:鸿蒙 @ohos.measure 的六个绑定机制

鸿蒙 @ohos.measure namespace(API 9+)核心导出 MeasureText class(含 measureText/measureTextSize static 方法)+ MeasureOptions interface + SizeOptions 返回类型。绑定机制来自六重根因。

机制 1:MeasureText.measureText 返回 number 不是 TextMetrics——React measureText 返回 TextMetrics 差异

鸿蒙坑根因:MeasureText.measureText(options) 返回 number(文本单行宽度 px),不是 React measureText 返回的 TextMetrics 对象:

// ❌ 鸿蒙坑:measureText 返回 number 不是 TextMetrics(直接取 .width 字段编译错)
import measure from '@ohos.measure'

// ❌ 直接取 .width 字段编译错(number 类型没有 width 字段)
const metrics = measure.MeasureText.measureText({ textContent: 'hello' })
// console.info(metrics.width)  // ❌ Property 'width' does not exist on type 'number'

// ✅ 正确用法:measureText 直接返回 number(文本单行宽度 px)
const width: number = measure.MeasureText.measureText({
  textContent: 'hello harmony measure',
  fontSize: '16fp',
  fontWeight: FontWeight.Normal
})
console.info('width: ' + width)  // ✅ width 是 number(px 单位)
// 鸿蒙坑根因:measureText 返回 number 不是 TextMetrics,React canvas.measureText 返回 TextMetrics

measureText 返回 number 坑根因:鸿蒙 MeasureText.measureText(options: MeasureOptions): number 的返回类型是 number(文本单行宽度,px 单位),不是 React canvas.measureText 返回的 TextMetrics 对象。鸿蒙坑:前端开发者习惯 React ctx.measureText(text).width 取宽度字段(TextMetrics.width),鸿蒙 measure.MeasureText.measureText(options) 直接返回 number——metrics.width 触发 Property 'width' does not exist on type 'number' 编译错。鸿蒙 measureText 只测单行宽度,不返回 actualBoundingBox/fontBoundingBox 多字段(React TextMetrics 含这些字段),鸿蒙设计简化返回 number 直接用。

机制 2:measureTextSize 返回 SizeOptions 不是 measureText 的 number——多行文本测量

鸿蒙坑根因:MeasureText.measureTextSize(options) 返回 SizeOptionswidth+height),用于多行文本测量,不是 measureText 返回的 number

// ❌ 鸿蒙坑:多行文本用 measureText 只返回单行宽度 number(不返回 height)
import measure from '@ohos.measure'

// ❌ 多行文本用 measureText 只返回单行宽度(不返回 height,无法知道多行总高)
const singleWidth: number = measure.MeasureText.measureText({
  textContent: '第一行\n第二行\n第三行',  // ❌ 多行文本 measureText 只测第一行宽度
  fontSize: '16fp'
})
// singleWidth 是第一行宽度 number(不返回 height,多行总高未知)

// ✅ 正确用法:多行文本用 measureTextSize 返回 SizeOptions(width + height)
const size: SizeOptions = measure.MeasureText.measureTextSize({
  textContent: '第一行\n第二行\n第三行',  // ✅ 多行文本 measureTextSize 返回 width + height
  fontSize: '16fp',
  maxWidth: 200  // ✅ maxWidth 限制宽度触发换行(maxWidth 200px 超过换行)
})
console.info('width: ' + size.width)   // ✅ SizeOptions.width 多行文本总宽 px
console.info('height: ' + size.height) // ✅ SizeOptions.height 多行文本总高 px
// 鸿蒙坑根因:measureTextSize 返回 SizeOptions(width+height),measureText 返回 number

measureTextSize SizeOptions 坑根因:鸿蒙 MeasureText.measureTextSize(options: MeasureOptions): SizeOptions 的返回类型是 SizeOptions(含 width: number + height: number),用于多行文本测量(文本含 \n 换行符或超过 maxWidth 触发换行时,measureTextSize 返回多行总宽 + 总高)。鸿蒙坑:多行文本测量用 measureText 只返回单行宽度 number(不返回 height,多行总高未知),必须用 measureTextSize 返回 SizeOptionswidth+height)。React canvas.measureText 只测单行返回 TextMetrics.width(React canvas 不支持多行文本测量,要手动逐行测累加),鸿蒙 measureTextSize 直接支持多行返回 SizeOptions(鸿蒙设计更贴合 ArkUI Text 组件多行场景)。

机制 3:MeasureOptions 必填 textContent 不是 text 字段——fontSize/fontWeight 可选

鸿蒙坑根因:MeasureOptions 必填字段 textContent: string | Resource(不是 text 字段),可选 fontSize/fontWeight/fontFamily/letterSpacing/maxWidth/lineHeight/overflow

// ❌ 鸿蒙坑:MeasureOptions 必填 textContent 不是 text 字段(用 text 字段编译错)
import measure from '@ohos.measure'

// ❌ 用 text 字段编译错(MeasureOptions 没有 text 字段,应是 textContent)
const w1 = measure.MeasureText.measureText({
  text: 'hello harmony',  // ❌ text 字段不存在(MeasureOptions 用 textContent)
  fontSize: '16fp'
})

// ❌ MeasureOptions.fontSize 传 string 必须带单位("16fp" 不是 "16")
const w2 = measure.MeasureText.measureText({
  textContent: 'hello',
  fontSize: '16'  // ❌ "16" 不带单位运行错(应是 "16fp" 或 "16px" 或 number 16)
})

// ✅ 正确用法:MeasureOptions 必填 textContent(string | Resource),可选 fontSize/fontWeight
const w3: number = measure.MeasureText.measureText({
  textContent: 'hello harmony measure',  // ✅ textContent 必填(string 或 Resource)
  fontSize: '16fp',   // ✅ fontSize 可选(string "16fp" 带单位,或 number 16 px)
  fontWeight: FontWeight.Normal,  // ✅ fontWeight 可选 enum
  fontFamily: 'sans-serif',  // ✅ fontFamily 可选(默认 sans-serif)
  letterSpacing: 1,  // ✅ letterSpacing 可选 number(px 单位)
  maxWidth: 200  // ✅ maxWidth 可选(超过触发换行,measureTextSize 时生效)
})
// 鸿蒙坑根因:MeasureOptions 必填 textContent 不是 text,fontSize string 须带单位

MeasureOptions textContent 坑根因:鸿蒙 MeasureOptions interface 的必填字段是 textContent: string | Resource(不是 React measureText(text)text 参数),可选字段 fontSize?: number | string | Resourcenumber 默认 px 单位,string 必须带单位 “16fp”/“16px”,Resource$r('app.float.size') 引用)/fontWeight?: FontWeight(enum 常量不是数字)/fontFamily?: string(默认 sans-serif)/letterSpacing?: number(px 单位)/maxWidth?: number | string | Resource(超过触发换行)/lineHeight?: number | string | Resource(行高)/overflow?: string(溢出处理)。鸿蒙坑:React ctx.measureText(text) 用位置参数传 text,鸿蒙 MeasureText.measureText(options) 用对象 textContent 字段——用 text 字段触发 Property 'text' does not exist on type 'MeasureOptions' 编译错;fontSizestring 必须带单位(“16” 不带单位运行错,应是 “16fp” 或 “16px”),传 number 默认 px 单位(React fontSize 默认 px 一致)。

机制 4:MeasureText.measureText/measureTextSize 废弃迁移 UIContext.getMeasureUtils()

鸿蒙坑根因:MeasureText.measureText/measureTextSize static 方法废弃(API 18 废弃),迁移到 UIContext.getMeasureUtils() 实例方法:

// ❌ 鸿蒙坑:MeasureText.measureText static 废弃(API 18 废弃,IDE 警告 deprecated)
import measure from '@ohos.measure'

// ❌ 废弃 API(API 9~17):MeasureText.measureText static 有 IDE 警告
const w1 = measure.MeasureText.measureText({ textContent: 'hello' })  // ❌ 废弃 deprecated IDE 警告
const s1 = measure.MeasureText.measureTextSize({ textContent: 'hello' })  // ❌ 废弃 deprecated

// ✅ 正确用法:getUIContext().getMeasureUtils() 实例方法(API 18,不废弃)
import { getUIContext } from '@kit.ArkUI'  // ✅ getUIContext 从 @kit.ArkUI
const measureUtils = getUIContext().getMeasureUtils()  // ✅ getMeasureUtils() 造实例
const w2: number = measureUtils.measureText({  // ✅ 实例方法 measureText(不是 static)
  textContent: 'hello harmony measure',
  fontSize: '16fp',
  fontWeight: FontWeight.Normal
})
const s2: SizeOptions = measureUtils.measureTextSize({  // ✅ 实例方法 measureTextSize
  textContent: '多行文本\n第二行',
  fontSize: '16fp',
  maxWidth: 200
})
// 鸿蒙坑根因:MeasureText.measureText static 废弃迁移 getMeasureUtils 实例方法

measureText static 废弃坑根因:鸿蒙 MeasureText.measureText/measureTextSizeMeasureText class 的 static 方法(API 9~至今可用,但 API 18 标记 deprecated),废弃迁移到 UIContext.getMeasureUtils(): MeasureUtils 实例方法(MeasureUtils.measureText(options): number + MeasureUtils.measureTextSize(options): SizeOptions)。鸿蒙坑:用废弃 measure.MeasureText.measureText 不会编译错(deprecated 不是 removed),但 IDE 警告 'measureText' has been deprecated. Use ohos.arkui.UIContext.MeasureUtils#measureText instead(d.ts 里 @useinstead ohos.arkui.UIContext.MeasureUtils#measureText),新代码必须 getUIContext().getMeasureUtils().measureText(options)(实例方法不废弃,签名跟 static 一致只是改实例方法)。React canvas.measureText 没有 deprecated 版本,鸿蒙 measureText deprecated 是因为 API 18 把测量统一到 UIContext 实例方法(跟篇 6 animator.create 废弃迁移 getUIContext().createAnimator()、篇 9 router.push 废弃迁移 pushUrl、篇 10 promptAction.showToast 废弃迁移 getPromptAction() 同理)。

机制 5:MeasureUtils 实例方法签名跟 MeasureText static 一致——只改 static 为实例方法

鸿蒙坑根因:MeasureUtils 实例方法签名跟 MeasureText static 一致(measureText(options): number + measureTextSize(options): SizeOptions),只是从 static 改实例方法:

// ✅ MeasureUtils 实例方法签名(跟 MeasureText static 一致,只改 static 为实例方法)
import { getUIContext } from '@kit.ArkUI'

const measureUtils = getUIContext().getMeasureUtils()  // ✅ getMeasureUtils() 造实例

// ✅ 实例方法 measureText(签名同 static MeasureText.measureText)
const width: number = measureUtils.measureText({
  textContent: 'hello harmony',
  fontSize: '16fp',
  fontWeight: FontWeight.Normal
})
// ✅ 实例方法 measureTextSize(签名同 static MeasureText.measureTextSize)
const size: SizeOptions = measureUtils.measureTextSize({
  textContent: '多行\n文本',
  fontSize: '16fp',
  maxWidth: 200
})

// ❌ MeasureUtils 不是 static class(不能 MeasureUtils.measureText 调用)
// const w = MeasureUtils.measureText({ textContent: 'hello' })  // ❌ MeasureUtils 不是 static class
// 鸿蒙坑根因:MeasureUtils 实例方法签名同 MeasureText static,只改 static 为实例方法

MeasureUtils 实例方法签名坑根因:鸿蒙 MeasureUtils class 的实例方法签名跟 MeasureText static 方法完全一致——measureText(options: MeasureOptions): number(单行宽度 px)+ measureTextSize(options: MeasureOptions): SizeOptions(多行 width+height),只是从 MeasureText.measureText static 调用改为 measureUtils.measureText 实例调用。鸿蒙坑:前端开发者习惯 React canvas.measureText 实例方法(ctx.measureText),鸿蒙 MeasureText.measureText static 改 MeasureUtils.measureText 实例方法——签名一致只是 static 改实例方法(measure.MeasureText.measureTextgetUIContext().getMeasureUtils().measureText),参数 MeasureOptions 和返回类型 number/SizeOptions 完全不变(迁移成本最低,只改调用方式)。

机制 6:MeasureOptions.fontSize 单位 number px / string “16fp” 带 fp 单位

鸿蒙坑根因:MeasureOptions.fontSize 单位是 number(px)或 string(“16fp” 带 fp 单位)或 Resource,传 number 默认 px 不是 fp:

// ❌ 鸿蒙坑:fontSize 传 string "16" 不带单位运行错(必须 "16fp" 或 "16px")
import measure from '@ohos.measure'

// ❌ fontSize 传 "16" 不带单位运行错(string 必须带 fp/px 单位)
const w1 = measure.MeasureText.measureText({
  textContent: 'hello',
  fontSize: '16'  // ❌ "16" 不带单位运行错(测量结果错误或 0)
})

// ❌ fontSize 传 number 16 默认 px 单位(不是 fp,跟 ArkUI Text.fontSize 默认 fp 不同)
const w2 = measure.MeasureText.measureText({
  textContent: 'hello',
  fontSize: 16  // ❌ number 16 默认 px 单位(不是 fp,跟 ArkUI Text.fontSize 默认 fp 不同)
})

// ✅ 正确用法:fontSize 传 string "16fp" 带 fp 单位(推荐,跟 ArkUI Text.fontSize 一致)
const w3: number = measure.MeasureText.measureText({
  textContent: 'hello harmony measure',
  fontSize: '16fp',  // ✅ "16fp" 带 fp 单位(推荐,跟 ArkUI Text.fontSize 一致)
  fontWeight: FontWeight.Normal
})

// ✅ fontSize 传 Resource 引用($r('app.float.size') 全局字体大小)
const w4: number = measure.MeasureText.measureText({
  textContent: 'hello',
  fontSize: $r('app.float.text_size')  // ✅ Resource 引用全局字体大小
})
// 鸿蒙坑根因:fontSize number 默认 px,string 须带 fp/px 单位,推荐 "16fp" 跟 ArkUI 一致

MeasureOptions fontSize 单位坑根因:鸿蒙 MeasureOptions.fontSize 的类型是 number | string | Resource(可选,默认 16px),number 默认 px 单位(不是 fp,跟 ArkUI Text.fontSize 默认 fp 不同),string 必须带单位 “16fp”/“16px”(“16” 不带单位运行错,测量结果错误或 0),Resource$r('app.float.size') 引用资源。鸿蒙坑:前端开发者习惯 React fontSize: 16 默认 px(一致),但鸿蒙 ArkUI Text.fontSize 默认 fp(flexible pixel,随屏幕密度缩放),MeasureOptions.fontSizenumber 默认 px(不随密度缩放)——测量 ArkUI Text 组件时 fontSize 应传 "16fp" 字符串带 fp 单位(跟 Text.fontSize 一致),传 number 16 默认 px 测量结果跟实际渲染不符(ArkUI Text 用 fp 渲染,测量用 px 算,数值不匹配)。

三、真机配图:鸿蒙 @ohos.measure 文本测量坑——measureText 返回 number + measureTextSize SizeOptions + getMeasureUtils 不废弃

measure 初始态 measureText number 态 measureTextSize SizeOptions 态 getMeasureUtils 不废弃 态 MeasureOptions textContent 态

真机配图展示鸿蒙 @ohos.measure 文本测量坑:

  • measure 初始态:鸿蒙 6.1 @ohos.measure 文本测量坑标题,4 个验证按钮(① measureText 返回 number / ② measureTextSize 返回 SizeOptions / ③ getMeasureUtils 不废弃 / ④ MeasureOptions textContent 必填),要点说明 7 条
  • measureText number 态:点击「① 验证 measureText 返回 number」按钮,显示「✅ measureText 返回 number(单行宽度 px),不是 TextMetrics 对象」+ width 值——measureText 返回 number 不是 TextMetrics 验证
  • measureTextSize SizeOptions 态:点击「② 验证 measureTextSize 返回 SizeOptions」按钮,显示「✅ measureTextSize 返回 SizeOptions(width + height),多行文本测量」+ width/height 值——measureTextSize SizeOptions 多行测量验证
  • getMeasureUtils 不废弃 态:点击「③ 验证 getMeasureUtils 不废弃」按钮,显示「✅ getUIContext().getMeasureUtils() 实例方法(不废弃),measureText/measureTextSize 实例方法」——getMeasureUtils 实例方法不废弃验证
  • MeasureOptions textContent 态:点击「④ 验证 MeasureOptions textContent 必填」按钮,显示「✅ MeasureOptions 必填 textContent(不是 text 字段),fontSize string 须带 fp/px 单位」——MeasureOptions textContent 必填 + fontSize 单位验证

四、真解法:鸿蒙 @ohos.measure 的四个场景

场景 1:getMeasureUtils().measureText 测单行文本宽度返回 number——90% 场景首选

单行文本宽度测量用 getUIContext().getMeasureUtils().measureText(options) + MeasureOptionstextContent 必填:

// ✅ 场景 1:getMeasureUtils().measureText 测单行文本宽度返回 number(API 18,90% 场景首选)
import { getUIContext } from '@kit.ArkUI'  // ✅ getUIContext 从 @kit.ArkUI 不是 @ohos.measure

@Entry
@Component
struct Index {
  @State textWidth: number = 0
  @State measuredText: string = 'hello harmony measure'

  measureSingleLine() {
    // ✅ getUIContext().getMeasureUtils() 造实例(不是废弃的 MeasureText.measureText static)
    const measureUtils = getUIContext().getMeasureUtils()
    // ✅ measureText 带 MeasureOptions(textContent 必填,不是 text 字段)
    this.textWidth = measureUtils.measureText({
      textContent: this.measuredText,  // ✅ textContent 必填(string | Resource)
      fontSize: '16fp',  // ✅ fontSize string 带 fp 单位(推荐,跟 ArkUI Text.fontSize 一致)
      fontWeight: FontWeight.Normal,  // ✅ fontWeight 可选 enum
      fontFamily: 'sans-serif',  // ✅ fontFamily 可选(默认 sans-serif)
      letterSpacing: 1  // ✅ letterSpacing 可选 number(px 单位)
    })
    // ✅ measureText 返回 number(文本单行宽度 px),直接赋值 @State textWidth
  }

  build() {
    Column({ space: 8 }) {
      Text('文本:' + this.measuredText).fontSize(16)
      Text('测量宽度:' + this.textWidth + ' px').fontSize(16)
      Button('测量单行宽度').onClick(() => this.measureSingleLine())
    }
  }
}
// getMeasureUtils + measureText + MeasureOptions.textContent:90% 场景首选,返回 number 单行宽度

鸿蒙 @ohos.measure API 真名坑import measure from '@ohos.measure'(default import,measure 是 namespace,含 MeasureText class);measure.MeasureText.measureText(options: MeasureOptions): number(static 方法,返回 number 单行宽度 px,API 18 废弃);measure.MeasureText.measureTextSize(options: MeasureOptions): SizeOptions(static 方法,返回 SizeOptionswidth+height,API 18 废弃);MeasureOptions interface 必填 textContent: string | Resource(不是 text 字段),可选 fontSize/fontWeight/fontFamily/letterSpacing/maxWidth/lineHeight/overflowSizeOptions interface 含 width: number + height: number(多行文本总宽 + 总高 px);废弃迁移到 getUIContext().getMeasureUtils(): MeasureUtils 实例方法(API 18,签名跟 static 一致只是改实例方法);SysCap SystemCapability.ArkUI.ArkUI.Full@atomicservice 原子化服务(API 12+);@crossplatform 跨平台(API 11+)。

场景 2:getMeasureUtils().measureTextSize 测多行文本返回 SizeOptions——width+height

多行文本测量用 getUIContext().getMeasureUtils().measureTextSize(options) + maxWidth 触发换行 + 返回 SizeOptionswidth+height):

// ✅ 场景 2:getMeasureUtils().measureTextSize 测多行文本返回 SizeOptions(API 18)
import { getUIContext } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  @State multiWidth: number = 0
  @State multiHeight: number = 0
  @State multiText: string = '第一行文本\n第二行文本\n第三行文本'  // ✅ \n 换行符触发多行

  measureMultiLine() {
    const measureUtils = getUIContext().getMeasureUtils()
    // ✅ measureTextSize 返回 SizeOptions(width + height),多行文本测量
    const size: SizeOptions = measureUtils.measureTextSize({
      textContent: this.multiText,  // ✅ textContent 带 \n 换行符(多行文本)
      fontSize: '16fp',
      fontWeight: FontWeight.Normal,
      maxWidth: 200,  // ✅ maxWidth 限制宽度 200px,超过触发换行(measureTextSize 时生效)
      lineHeight: '24fp',  // ✅ lineHeight 行高(多行文本总高 = 行数 × lineHeight)
      overflow: TextOverflow.Ellipsis  // ✅ overflow 溢出处理(Ellipsis 省略号)
    })
    this.multiWidth = size.width   // ✅ SizeOptions.width 多行文本总宽 px
    this.multiHeight = size.height // ✅ SizeOptions.height 多行文本总高 px
  }

  build() {
    Column({ space: 8 }) {
      Text('多行文本:' + this.multiText).fontSize(16)
      Text('总宽:' + this.multiWidth + 'px,总高:' + this.multiHeight + 'px').fontSize(16)
      Button('测量多行宽高').onClick(() => this.measureMultiLine())
    }
  }
}
// measureTextSize + SizeOptions + maxWidth:多行文本测量,返回 width+height

鸿蒙 measureTextSize + SizeOptions API 真名坑MeasureUtils.measureTextSize(options: MeasureOptions): SizeOptions(实例方法,返回 SizeOptionswidth+height);SizeOptions interface 含 width: number + height: number(多行文本总宽 + 总高 px);MeasureOptions.maxWidth 限制宽度触发换行(超过 maxWidth 自动换行,measureTextSize 返回多行总宽 + 总高);MeasureOptions.lineHeight 行高(多行总高 = 行数 × lineHeight);MeasureOptions.overflow 溢出处理(TextOverflow.Ellipsis 省略号,TextOverflow.Clip 裁剪);鸿蒙坑:多行文本测量用 measureText 只返回单行宽度 number(不返回 height,多行总高未知),必须用 measureTextSize 返回 SizeOptionswidth+height);React canvas.measureText 只测单行返回 TextMetrics.width(React canvas 不支持多行文本测量,要手动逐行测累加),鸿蒙 measureTextSize 直接支持多行返回 SizeOptions(鸿蒙设计更贴合 ArkUI Text 组件多行场景)。

场景 3:getMeasureUtils().measureText 测量 ArkUI Text 组件宽度——fontSize “16fp” 跟 Text 一致

测量 ArkUI Text 组件实际渲染宽度用 getMeasureUtils().measureText(options) + fontSize"16fp" 字符串带 fp 单位(跟 Text.fontSize 一致):

// ✅ 场景 3:getMeasureUtils().measureText 测量 ArkUI Text 组件宽度(fontSize "16fp" 跟 Text 一致)
import { getUIContext } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  @State textWidth: number = 0
  @State measuredText: string = '测量 ArkUI Text 组件实际渲染宽度'
  @State textSize: number = 16  // ✅ ArkUI Text.fontSize 用 fp 单位(16fp)

  measureTextComponent() {
    const measureUtils = getUIContext().getMeasureUtils()
    // ✅ fontSize 传 string "16fp" 带 fp 单位(跟 ArkUI Text.fontSize 一致,测量结果匹配实际渲染)
    this.textWidth = measureUtils.measureText({
      textContent: this.measuredText,
      fontSize: `${this.textSize}fp`,  // ✅ "16fp" 带 fp 单位(推荐,跟 ArkUI Text.fontSize 一致)
      fontWeight: FontWeight.Normal,
      fontFamily: 'sans-serif',
      letterSpacing: 1
    })
    // ✅ textWidth 是 ArkUI Text 组件实际渲染宽度 px(fontSize "16fp" 跟 Text.fontSize 一致)
  }

  build() {
    Column({ space: 8 }) {
      Text(this.measuredText).fontSize(this.textSize).fontWeight(FontWeight.Normal)
      Text('Text 组件渲染宽度:' + this.textWidth + ' px').fontSize(16)
      Button('测量 Text 组件宽度').onClick(() => this.measureTextComponent())
    }
  }
}
// measureText + fontSize "16fp":测量 ArkUI Text 组件宽度,fontSize 带 fp 单位跟 Text 一致

鸿蒙 measureText 测 ArkUI Text 组件 API 真名坑:测量 ArkUI Text 组件实际渲染宽度时,MeasureOptions.fontSize 应传 string "16fp" 带 fp 单位(跟 ArkUI Text.fontSize 默认 fp 一致),不传 number 16(默认 px 单位,不随密度缩放,测量结果跟实际渲染不符);MeasureOptions.fontWeightFontWeight.Normal enum 常量(不是数字 400,不是字符串 “normal”);MeasureOptions.fontFamily"sans-serif"(默认 sans-serif,跟 ArkUI Text.fontFamily 一致);MeasureOptions.letterSpacingnumber 1(px 单位,跟 ArkUI Text.letterSpacing 一致);鸿蒙坑:React canvas.measureText 先设 ctx.font = '16px sans-serif' 再测,鸿蒙 measureTextfont 信息全部传 MeasureOptions 字段(fontSize/fontWeight/fontFamily/letterSpacing),不设全局 ctx.font;测量结果 number 是 px 单位(不是 fp),ArkUI Text 组件宽度也是 px 单位(fp 转 px 后渲染),数值匹配。

场景 4:getMeasureUtils().measureText 自适应文本宽度——动态计算布局

自适应文本宽度用 getMeasureUtils().measureText(options) 动态计算文本宽度,调整布局(如 Column 宽度跟随文本宽度):

// ✅ 场景 4:getMeasureUtils().measureText 自适应文本宽度(动态计算布局)
import { getUIContext } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  @State dynamicText: string = '自适应文本宽度'
  @State textWidth: number = 100  // ✅ 默认宽度 100px,测量后更新
  @State textSize: number = 16

  aboutToAppear() {
    this.updateTextWidth()  // ✅ 组件出现时先测量一次
  }

  updateTextWidth() {
    const measureUtils = getUIContext().getMeasureUtils()
    // ✅ measureText 测量当前文本宽度,动态更新 @State textWidth
    this.textWidth = measureUtils.measureText({
      textContent: this.dynamicText,
      fontSize: `${this.textSize}fp`,
      fontWeight: FontWeight.Normal,
      fontFamily: 'sans-serif',
      letterSpacing: 1
    })
    // ✅ textWidth 跟随 dynamicText 变化动态更新(Column 宽度跟随)
  }

  build() {
    Column({ space: 8 }) {
      // ✅ Column 宽度跟随 textWidth(测量结果 + padding 20px)
      Column() {
        Text(this.dynamicText).fontSize(this.textSize).fontWeight(FontWeight.Normal)
      }
      .width(this.textWidth + 20)  // ✅ 动态宽度(测量文本宽度 + padding 20px)
      .padding(10)
      .backgroundColor('#F0F0F0')

      TextInput('输入文本', this.dynamicText)
        .width('90%')
        .onChange((value: string) => {
          this.dynamicText = value
          this.updateTextWidth()  // ✅ 文本变化时重新测量更新宽度
        })

      Text('测量宽度:' + this.textWidth + 'px,布局宽度:' + (this.textWidth + 20) + 'px')
        .fontSize(14)
    }
  }
}
// measureText 自适应文本宽度:动态计算文本宽度调整布局(Column 宽度跟随文本宽度)

鸿蒙 measureText 自适应布局 API 真名坑getMeasureUtils().measureText(options)aboutToAppear 生命周期先测量一次(组件出现时文本宽度已知),onChange 回调里文本变化时重新测量更新 @State textWidth(触发 UI 重渲染,Column 宽度跟随);MeasureOptionstextContent/fontSize/fontWeight/fontFamily/letterSpacing 必须跟 ArkUI Text 组件的对应属性完全一致(fontSize 用 fp,fontWeight 用 enum,fontFamily 用 sans-serif,letterSpacing 用 px),否则测量结果跟实际渲染不符;鸿蒙坑:React 自适应文本宽度用 useLayoutEffect + ref.offsetWidth 测量实际 DOM 宽度(浏览器渲染后测量),鸿蒙 measureText 在渲染前测量文本宽度(预测渲染宽度,不需要等渲染完成),测量结果是预测值(px 单位),实际渲染宽度可能因字体加载延迟略有差异(鸿蒙 measureText 用系统默认字体测量,自定义字体加载后需重新测量)。

五、一句话哲学

写鸿蒙 ArkTS 记住:measure 不是浏览器 canvas measureText 是「namespace static MeasureText + MeasureOptions」——鸿蒙 6.1 API 23 @ohos.measure namespace(API 9+,鸿蒙 6.1 API 23 基座,MeasureText class 含 measureText/measureTextSize static 方法 + MeasureOptions interface + SizeOptions 返回类型,SysCap SystemCapability.ArkUI.ArkUI.Full,@atomicservice,@crossplatform,API 18 废弃迁移到 UIContext.getMeasureUtils() 实例方法)。根因不是方法是 static——MeasureText.measureText(options: MeasureOptions): number 返回 number(文本单行宽度 px)不是 React canvas.measureText 返回的 TextMetrics 对象(✅ const width: number = measureUtils.measureText(options) 直接用 number,❌ metrics.width 触发 Property 'width' does not exist on type 'number' 编译错,React TextMetrics.width 命名差异),MeasureText.measureTextSize(options: MeasureOptions): SizeOptions 返回 SizeOptions(含 width: number + height: number)用于多行文本测量(✅ 多行文本 \n 换行符或超过 maxWidth 触发换行时用 measureTextSize 返回 SizeOptions,❌ 多行文本用 measureText 只返回单行宽度 number 不返回 height,React canvas.measureText 只测单行不支持多行),MeasureOptions interface 必填字段 textContent: string | Resource(✅ textContent 不是 text 字段,❌ 用 text 字段触发 Property 'text' does not exist on type 'MeasureOptions' 编译错,React measureText(text) 位置参数差异),可选字段 fontSize?: number | string | Resource(✅ string 必须带单位 "16fp"/"16px"number 默认 px 单位,Resource$r('app.float.size'),❌ fontSize: "16" 不带单位运行错,❌ fontSize: 16 默认 px 不是 fp 跟 ArkUI Text.fontSize 默认 fp 不一致)/fontWeight?: FontWeight(enum 常量不是数字 400 不是字符串 “normal”)/fontFamily?: string(默认 sans-serif)/letterSpacing?: number(px 单位)/maxWidth?: number | string | Resource(超过触发换行,measureTextSize 时生效)/lineHeight?: number | string | Resource(行高,多行总高 = 行数 × lineHeight)/overflow?: string(溢出处理),MeasureText.measureText/measureTextSize static 方法废弃(API 18 废弃,IDE 警告 'measureText' has been deprecated. Use ohos.arkui.UIContext.MeasureUtils#measureText instead,d.ts 里 @useinstead ohos.arkui.UIContext.MeasureUtils#measureText),迁移到 getUIContext().getMeasureUtils(): MeasureUtils 实例方法(✅ getUIContext().getMeasureUtils().measureText(options) 实例方法不废弃,签名跟 static 一致只是改实例方法,MeasureUtils.measureText(options): number + MeasureUtils.measureTextSize(options): SizeOptions,❌ MeasureUtils.measureText 不能 static 调用,必须先 getMeasureUtils() 造实例),SizeOptions interface 含 width: number + height: number(多行文本总宽 + 总高 px)。measureText 返回 number 不是 TextMetrics + measureTextSize 返回 SizeOptions 多行测量 + MeasureOptions 必填 textContent 不是 text + fontSize string 须带 fp/px 单位 + MeasureText static 废弃迁移 getMeasureUtils 实例方法 是鸿蒙 6.1 @ohos.measure 文本测量坑核心!

能力系列回链

  • 鸿蒙 7.0 新特性篇 1~17(沉浸式毛玻璃/Component3D/智能体框架/方舟引擎/星盾安全/星河互联/空间音频/可变字体/游戏快启/分布式数据盾/LTPO 可变帧率/AI 文档识别/多形态服务窗口/AI 反诈/机密计算/空间计算/小艺全面进化)
  • 鸿蒙 6.1 API 23 开发坑系列篇 1「ArkUI.modifier 装饰器坑」——attributeModifier + AttributeModifier 状态化节点修改器
  • 鸿蒙 6.1 API 23 开发坑系列篇 2「arkui.componentSnapshot 组件截图坑」——get/getSync/createFromBuilder 返回 image.PixelMap 像素图
  • 鸿蒙 6.1 API 23 开发坑系列篇 3「arkui.node 节点坑」——NodeController abstract class makeNode override + BuilderNode WrappedBuilder
  • 鸿蒙 6.1 API 23 开发坑系列篇 4「arkui.UIContext UI 上下文坑」——runScopedTask 不是 runScopedOnUiThread + 11 个子管理器
  • 鸿蒙 6.1 API 23 开发坑系列篇 5「arkui.observer UI 观察器坑」——uiObserver namespace 真名不是 observer + on type string literal
  • 鸿蒙 6.1 API 23 开发坑系列篇 6「@ohos.animator 动画器坑」——import @kit.ArkUI 不是 @ohos.animator + onFrame 驼峰不是废弃 onframe + getUIContext().createAnimator 不是废弃 animator.create + 持引用 + aboutToDisappear cancel
  • 鸿蒙 6.1 API 23 开发坑系列篇 7「@ohos.net.http HTTP 请求坑」——HttpDataType 常量是 STRING 不是 STRING_TYPE + HttpRequest 是 interface 不能 new + http.createHttp() 工厂造实例 + on/off 监听不是 addEventListener + header Record 不是 Headers + RequestMethod enum 不是字符串
  • 鸿蒙 6.1 API 23 开发坑系列篇 8「@ohos.file.fs 文件管理坑」——writeSync/readSync 是 namespace 顶层函数不是 File 实例方法 + 第一参传 file.fd 文件描述符 + ReadOptions 无 encoding 读 ArrayBuffer 原字节 + WriteOptions 带 encoding 写字符串指定编码 + closeSync(file) 传 File 不是 fd + OpenMode enum 不是 flags 数字
  • 鸿蒙 6.1 API 23 开发坑系列篇 9「@ohos.router 页面路由坑」——router.push/replace 废弃迁移 pushUrl/replaceUrl + RouterMode enum 常量 Standard/Single 不是字符串 + RouterOptions.url 绝对路径不是相对路径 + getParams 返回 Object 要 as Record 转型 + RouterState 真属性 index/name 不是 stackLength + getLength 返回 string 不是 number
  • 鸿蒙 6.1 API 23 开发坑系列篇 10「@ohos.promptAction 弹窗坑」——showToast/showDialog/showActionMenu 废弃迁移 getPromptAction + ToastType enum 常量 Default/Bottom/Center/Top 不是字符串 + ShowToastOptions.duration 单位 10ms 不是 1ms + showDialog 回调 onAccept/onCancel 不是 onConfirm/onAbort + DialogButton.action 不是 onClick 无 bgColor + showActionMenu buttons 上限 6 不是无限
  • 鸿蒙 6.1 API 23 开发坑系列篇 11「@ohos.measure 文本测量坑」——measureText 返回 number 不是 TextMetrics + measureTextSize 返回 SizeOptions 多行测量 + MeasureOptions 必填 textContent 不是 text + fontSize string 须带 fp/px 单位 + MeasureText static 废弃迁移 getMeasureUtils 实例方法(本文)
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐