harmony 鸿蒙文本测量(ArkTS)
文本测量(ArkTS)
场景介绍
文本测量指的是在图形绘制中,对文本的尺寸和布局进行评估,计算文本在给定字体和样式下占用的空间(例如宽度、高度和其他相关信息)的过程。文本测量用于文本排版、布局、渲染以及调整文本显示的位置和大小等场景,便于对界面的布局和呈现更好地把控和调整,以达到设计预期。
当前主要支持以下方面的文本测量能力:
文本宽度:测量给定文本在特定字体、大小和样式下的水平长度。
文本高度:测量给定文本的垂直高度,通常涉及文本的上升线、下降线等。
行间距:测量多行文本之间的垂直距离,通常与文本的行距相关。
字符间距:测量单个字符之间的水平距离,通常与字形和字体设计有关。
接口说明
文本测量中常用接口如下表所示,详细接口说明参考@ohos.graphics.text (文本模块)。
接口名 | 描述 |
---|---|
getLongestLine(): number | 获取当前段落最长行的宽度,建议实际使用时将返回值向上取整。 |
getLongestLineWithIndent(): number | 获取当前段落最长行的宽度(该宽度包含当前行缩进的宽度),建议实际使用时将返回值向上取整。 |
getTextLines(): Array<TextLine> | 获取当前段落文本行对象数组。 |
getLineMetrics(): Array<LineMetrics> | 获取段落所有行的度量信息。包含行的高度、宽度、起始坐标等信息。 |
getLineMetrics(lineNumber: number): LineMetrics |undefined | 获取段落指定行的度量信息。包含行的高度、宽度、起始坐标等信息。超出当前段落排版后最大行数后返回 undefined |
开发步骤
- 导入依赖的相关模块。
import { text } from '@kit.ArkGraphics2D';
- 创建段落样式,并使用构造段落生成器PargraphBuilder生成段落实例。
// 设置文本样式
let myTextStyle: text.TextStyle = {
color: { alpha: 255, red: 255, green: 0, blue: 0 },
fontSize: 100
};
// 创建一个段落样式对象,以设置排版风格
let myParagraphStyle: text.ParagraphStyle = {
textStyle: myTextStyle,
wordBreak:text.WordBreak.NORMAL
}
// 创建一个段落生成器
let paragraphBuilder: text.ParagraphBuilder = new text.ParagraphBuilder(myParagraphStyle, new text.FontCollection());
- 设置文本样式,添加文本内容,并生成段落文本用于后续文本的绘制显示。
// 在段落生成器中设置文本样式
paragraphBuilder.pushStyle(myTextStyle);
// 在段落生成器中设置文本内容
paragraphBuilder.addText("文本测量测试");
// 通过段落生成器生成段落
let paragraph = paragraphBuilder.build();
- 调用测量相关接口,获取指定的测量信息。
// case1: 获取排版后最长行行宽
let longestLineWidth = paragraph.getLongestLine();
// case2: 获取排版后最长行行宽(包含缩进)
let longestLineWithIndentWidth = paragraph.getLongestLineWithIndent()
// case3: 获取排版后所有行对象
let textLines = paragraph.getTextLines();
// case4: 获取排版后指定行对应的度量信息
let lineCnt = paragraph.getLineCount();
for (let index = 0; index < lineCnt; index++) {
let lineMetrics = paragraph.getLineMetrics(index);
}
// case5: 获取排版后所有行度量信息数组
let allLineMetrics = paragraph.getLineMetrics();
完整示例
完整的文本测量示例如下。
// Index.ets
import { NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI';
import { UIContext } from '@kit.ArkUI';
import { text } from '@kit.ArkGraphics2D';
// 创建一个自定义的渲染节点类,用于绘制文本
class MyRenderNode extends RenderNode {
async draw(context: DrawContext) {
// 获取画布canvas对象
const canvas = context.canvas;
// 配置文本样式(红色,字号100px)
let myTextStyle: text.TextStyle = {
color: {
alpha: 255,
red: 255,
green: 0,
blue: 0
},
fontSize: 100
};
// 创建一个段落样式对象,以设置排版风格
let myParagraphStyle: text.ParagraphStyle = {
textStyle: myTextStyle,
wordBreak: text.WordBreak.NORMAL
};
// 创建一个段落生成器
let paragraphBuilder = new text.ParagraphBuilder(myParagraphStyle, new text.FontCollection());
// 在段落生成器中设置文本样式
paragraphBuilder.pushStyle(myTextStyle);
// 在段落生成器中设置文本内容
paragraphBuilder.addText("文本测量测试");
// 通过段落生成器生成段落
let paragraph = paragraphBuilder.build();
// 布局
paragraph.layoutSync(1000);
// case1: 获取排版后最长行行宽
let longestLineWidth = paragraph.getLongestLine();
console.info("longestLineWidth = " + longestLineWidth);
// case2: 获取排版后最长行行宽(包含缩进)
let longestLineWithIndentWidth = paragraph.getLongestLineWithIndent();
console.info("longestLineWithIndentWidth = " + longestLineWithIndentWidth);
// case3: 获取排版后所有行对象
let textLines = paragraph.getTextLines();
for (let index = 0; index < textLines.length; index++) {
const textline = textLines[index];
let curLineRange = textline.getTextRange();
let curLineGlyCnt = textline.getGlyphCount();
console.info("MetricsMSG: 第" + (index + 1) + "行 TextRange start: " + curLineRange.start + " TextRange end: " + curLineRange.end);
console.info("MetricsMSG: 第" + (index + 1) + "行字形数量为: " + curLineGlyCnt);
}
// case4: 获取排版后指定行对应的度量信息
let lineCnt = paragraph.getLineCount();
for (let index = 0; index < lineCnt; index++) {
let lineMetrics = paragraph.getLineMetrics(index);
if (lineMetrics) {
console.info("MetricsMSG: 第" + (index + 1) + "行 lineMetrics width: " + lineMetrics.width);
console.info("MetricsMSG: 第" + (index + 1) + "行 lineMetrics start index: " + lineMetrics.startIndex + ", end index: " +
lineMetrics.endIndex);
}
}
// case5: 获取排版后所有行度量信息数组
let allLineMetrics = paragraph.getLineMetrics();
console.info("MetricsMSG: 第1行 lineMetrics width: " + allLineMetrics[0].width);
paragraph.paint(canvas, 0, 800);
}
}
// 创建文本渲染节点实例
const textNode = new MyRenderNode();
// 定义newNode的大小和位置
textNode.frame = { x: 0, y: 0, width: 400, height: 600 };
class MyNodeController extends NodeController {
private rootNode: FrameNode|null = null;
makeNode(uiContext: UIContext): FrameNode {
this.rootNode = new FrameNode(uiContext);
if (this.rootNode == null) {
return this.rootNode;
}
const renderNode = this.rootNode.getRenderNode();
if (renderNode != null) {
renderNode.frame = {
x: 0,
y: 0,
width: 300,
height: 50
};
renderNode.pivot = { x: 0, y: 0 };
}
return this.rootNode;
}
addNode(node: RenderNode): void {
if (this.rootNode == null) {
return;
}
const renderNode = this.rootNode.getRenderNode();
if (renderNode != null) {
renderNode.appendChild(node);
}
}
clearNodes(): void {
if (this.rootNode == null) {
return;
}
const renderNode = this.rootNode.getRenderNode();
if (renderNode != null) {
renderNode.clearChildren();
}
}
}
@Entry
@Component
struct RenderTest {
private myNodeController: MyNodeController = new MyNodeController();
build() {
Column() {
Row() {
NodeContainer(this.myNodeController)
.height('100%')
.position({ x: 30, y: 25 })
}
Row() {
Button("Draw Text")
.fontSize('16fp')
.fontWeight(500)
.margin({ bottom: 24, right: 12 })
.onClick(() => {
this.myNodeController.clearNodes();
this.myNodeController.addNode(textNode);
})
.width('50%')
.height(40)
}
.width('100%')
.justifyContent(FlexAlign.Center) // 设置当前Row容器内子元素在主轴上居中对齐
.alignItems(VerticalAlign.Bottom) // 设置当前Row容器内子元素在交叉轴(垂直方向)上的对齐方式为底部对齐
.layoutWeight(1) // 设置当前Row在父容器Column中的布局权重为1
}
}
}
你可能感兴趣的鸿蒙文章
harmony 鸿蒙ArkGraphics 2D(方舟2D图形服务)
harmony 鸿蒙画布的获取与绘制结果的显示(ArkTS)
0
赞
- 所属分类: 后端技术
- 本文标签:
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦