使用属性字符串
=======

部分框架或应用具备自研的文字排版能力，在移植时，其文字排版能力会被对接到[方舟2D图形服务的文本引擎](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/complex-text-c)。为了避免开发者重复开发文本组件，Text组件可以通过[ArkUI\_NodeAttributeType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-node-h#arkui_nodeattributetype)中的NODE\_TEXT\_CONTENT\_WITH\_STYLED\_STRING属性，使用格式化字符串对象设置文本内容属性，直接渲染方舟文本引擎生成的文本。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b6/v3/3NJt5voXRD2i0Gyccb9AAw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073316Z&HW-CC-Expire=86400&HW-CC-Sign=45E20246DDAC10712F648C041C97425FF5D5D7E22C6CCDE4FD2DF550320BA233)

*   本篇示例仅提供核心接口的调用方法，完整的示例工程请参考[StyledStringSample](https://gitcode.com/HarmonyOS_Samples/guide-snippets/tree/master/ArkUISample/StyledStringSample)。

以下示例代码基于[接入ArkTS页面章节](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ndk-access-the-arkts-page)，阐述了如何创建StyledString，并利用[ArkUI\_NodeType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-node-h#arkui_nodetype)为ARKUI\_NODE\_TEXT的组件进行渲染显示。

下图展示了 NODE\_TEXT\_CONTENT\_WITH\_STYLED\_STRING 接口的主要使用流程。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b9/v3/YLxZtOfrT3-FiC4mHGmOVg/zh-cn_image_0000002625107781.png?HW-CC-KV=V1&HW-CC-Date=20260612T073316Z&HW-CC-Expire=86400&HW-CC-Sign=F7F6EAF98624301BD30EDF223C6D63E577CA9AE413791BD848C000BC6A4B30C4)

#### 创建StyledString对象

使用[OH\_ArkUI\_StyledString\_Create](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_create)接口创建StyledString对象，需要传入[段落样式](#设置段落样式)。

// 创建StyledString并设置文本内容
ArkUI\_StyledString \*styledString = OH\_ArkUI\_StyledString\_Create(typographyStyle, fontCollection);

#### 通过StyledString设置样式

StyledString支持为文本中的不同部分设置不同的样式，包括段落样式和文本样式。

#### \[h2\]设置段落样式

通过如下接口可以设置StyledString的段落样式属性，包括最大行数、对齐方式等。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/63/v3/bMigy-APQkuuP2wJKiHIhQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073316Z&HW-CC-Expire=86400&HW-CC-Sign=4A18FB7AFF5946ACEBF9F491963E2455873B2B893533B0FFB438DA6D278550D1)

StyledString需要依赖OH\_Drawing\_前缀的方舟字体引擎接口进行字体以及段落样式的设置，参考[简单文本绘制与显示（C/C++）](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/simple-text-c)、[复杂文本绘制与显示（C/C++）](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/complex-text-c)。涉及字体引擎的接口，需在CMakeLists.txt中添加target\_link\_libraries(entry PUBLIC libnative\_drawing.so)，否则链接阶段会报错。

**表1** 段落样式设置接口

| 接口 | 描述 |
| :-- | :-- |
| [OH\_Drawing\_CreateFontCollection](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-font-collection-h#oh_drawing_createfontcollection) | 创建字体集对象。 |
| [OH\_Drawing\_CreateTypographyStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_createtypographystyle) | 创建段落样式对象。 |
| [OH\_Drawing\_SetTypographyTextAlign](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_settypographytextalign) | 设置文本对齐方式。 |
| [OH\_Drawing\_SetTypographyTextMaxLines](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_settypographytextmaxlines) | 设置文本最大行数。 |

以下代码示例设置了文字居中，最大行数限制为10。

// 创建字体集合与段落样式
OH\_Drawing\_FontCollection \*fontCollection = OH\_Drawing\_CreateFontCollection();
OH\_Drawing\_TypographyStyle \*typographyStyle = OH\_Drawing\_CreateTypographyStyle();
OH\_Drawing\_SetTypographyTextAlign(typographyStyle, OH\_Drawing\_TextAlign::TEXT\_ALIGN\_CENTER);
OH\_Drawing\_SetTypographyTextMaxLines(typographyStyle, NUM\_10);

#### \[h2\]设置文本样式

不同内容的文本可以通过StyledString设置不同的文本样式，但必须按照以下三个接口的逻辑调用顺序进行设置，否则将无法生效。

1.  [OH\_ArkUI\_StyledString\_PushTextStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_pushtextstyle)：将文字样式推入栈中。
2.  [OH\_ArkUI\_StyledString\_AddText](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_addtext)：添加要修改样式的文字内容。
3.  [OH\_ArkUI\_StyledString\_PopTextStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_poptextstyle)：将文字样式弹出栈。

**表2** 文本样式设置接口

| 接口 | 描述 |
| :-- | :-- |
| [OH\_Drawing\_CreateTextStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_createtextstyle) | 创建文本样式对象。 |
| [OH\_Drawing\_SetTextStyleFontSize](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_settextstylefontsize) | 设置字体大小。 |
| [OH\_Drawing\_SetTextStyleColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_settextstylecolor) | 设置字体颜色。 |

使用[OH\_Drawing\_CreateTextStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_createtextstyle)创建文本样式。以下示例设置"Hello"字体大小28px，颜色为0xFF707070，显示为灰色；设置"World!"字体大小为28px，颜色为0xFF2787D9，显示为蓝色。

// 第一段文本（灰色"Hello"）
OH\_Drawing\_TextStyle \*textStyle = OH\_Drawing\_CreateTextStyle();
OH\_Drawing\_SetTextStyleFontSize(textStyle, FONT\_SIZE);
OH\_Drawing\_SetTextStyleColor(textStyle, TEXT\_COLOR\_GRAY);
OH\_ArkUI\_StyledString\_PushTextStyle(styledString, textStyle);
OH\_ArkUI\_StyledString\_AddText(styledString, "Hello");
OH\_ArkUI\_StyledString\_PopTextStyle(styledString);

// 第二段文本（蓝色"World!"）
OH\_Drawing\_TextStyle \*worldTextStyle = OH\_Drawing\_CreateTextStyle();
OH\_Drawing\_SetTextStyleFontSize(worldTextStyle, FONT\_SIZE);
OH\_Drawing\_SetTextStyleColor(worldTextStyle, TEXT\_COLOR\_BLUE);
OH\_ArkUI\_StyledString\_PushTextStyle(styledString, worldTextStyle);
OH\_ArkUI\_StyledString\_AddText(styledString, "World!");
OH\_ArkUI\_StyledString\_PopTextStyle(styledString);

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ca/v3/AfdqXNbUQ5GK6J9vugWIug/zh-cn_image_0000002594668264.png?HW-CC-KV=V1&HW-CC-Date=20260612T073316Z&HW-CC-Expire=86400&HW-CC-Sign=9FEAEEFD9B5A2FF07E31B7D0C55698634095AF8C9329C7328A9B88C30F732A89)

#### 添加占位符

占位符功能主要用于图文混排场景，可以在文本中插入指定大小的空白区域，用于挂载Image组件或其他自定义内容。

使用[OH\_ArkUI\_StyledString\_AddPlaceholder](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_addplaceholder)接口在文本中插入占位符。

// 添加占位符
OH\_Drawing\_PlaceholderSpan placeHolder{.width = PLACEHOLDER\_WIDTH, .height = PLACEHOLDER\_HEIGHT};
OH\_ArkUI\_StyledString\_AddPlaceholder(styledString, &placeHolder);

#### 布局与绘制

StyledString在设置到Text组件之前，需要先完成布局计算，然后再进行渲染。

文字样式和内容设置完成后，调用字体引擎接口[OH\_Drawing\_TypographyLayout](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_typographylayout)对文本进行布局，传入最大宽度。超过此宽度的文字会自动换行。

OH\_Drawing\_Typography \*typography = OH\_ArkUI\_StyledString\_CreateTypography(styledString);
OH\_Drawing\_TypographyLayout(typography, LAYOUT\_MAX\_WIDTH);
// 布局完成后，将StyledString设置给Text组件
ArkUI\_AttributeItem styledStringItem = {.object = styledString};
nodeApi->setAttribute(text, NODE\_TEXT\_CONTENT\_WITH\_STYLED\_STRING, &styledStringItem);

#### 序列化与反序列化

从API version 14开始，StyledString提供了序列化和反序列化功能，支持将格式化字符串转换为字节数组或HTML格式，便于数据的存储、传输和跨平台使用。

**表3** 序列化与反序列化接口

| 接口 | 描述 |
| :-- | :-- |
| [OH\_ArkUI\_StyledString\_Descriptor\_Create](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_descriptor_create) | 创建StyledString描述符。 |
| [OH\_ArkUI\_UnmarshallStyledStringDescriptor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_unmarshallstyledstringdescriptor) | 反序列化字节数据到描述符。 |
| [OH\_ArkUI\_ConvertToHtml](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_converttohtml) | 将描述符转换为HTML格式。 |
| [OH\_ArkUI\_StyledString\_Descriptor\_Destroy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_descriptor_destroy) | 销毁StyledString描述符。 |

以下示例展示了如何创建描述符、反序列化字节数据、转换为HTML并进行验证。

static void SerializeAndDeserializeStyledString()
{
    // 准备测试数据
    uint8\_t data\_bytes\[\] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    size\_t dataSize = sizeof(data\_bytes) / sizeof(data\_bytes\[0\]);

    // 创建StyledString描述符
    auto desc = OH\_ArkUI\_StyledString\_Descriptor\_Create();
    if (desc == nullptr) {
        OH\_LOG\_Print(LOG\_APP, LOG\_ERROR, LOG\_PRINT\_DOMAIN, "styledString", "Create Descriptor failed");
        return;
    }

    // 反序列化字节数据
    auto status = OH\_ArkUI\_UnmarshallStyledStringDescriptor(data\_bytes, dataSize, desc);
    OH\_LOG\_Print(LOG\_APP, LOG\_ERROR, LOG\_PRINT\_DOMAIN, "styledString", "Unmarshall status: %{public}d", status);

    // 转换为HTML格式
    const char\* html = OH\_ArkUI\_ConvertToHtml(desc);
    OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "styledString", "html: \[%{public}s\]", html);
    size\_t resultSize = dataSize + 2;
    uint8\_t \*buf1 = (uint8\_t \*)malloc(10 \* sizeof(uint8\_t));
    if (buf1 == nullptr) {
        OH\_ArkUI\_StyledString\_Descriptor\_Destroy(desc);
        return;
    }
    OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "styledString", "resultSize: %{public}zu", resultSize);
    uint8\_t \*buf2 = (uint8\_t \*)malloc(resultSize \* sizeof(uint8\_t));

    // 序列化字节数组
    if (buf2 != nullptr) {
        if (resultSize >= dataSize) {
            for (size\_t i = 0; i < dataSize; i++) {
                buf2\[i\] = data\_bytes\[i\];
            }
        } else {
            OH\_LOG\_Print(LOG\_APP, LOG\_ERROR, LOG\_PRINT\_DOMAIN, "styledString",
                         "Buf too small: %{public}zu < %{public}zu", resultSize, dataSize);
            free(buf2);
            free(buf1);
            OH\_ArkUI\_StyledString\_Descriptor\_Destroy(desc);
            return;
        }
        bool equal = true;
        for (size\_t i = 0; i < dataSize && equal; i++) equal = (data\_bytes\[i\] == buf2\[i\]);
        OH\_LOG\_Print(LOG\_APP, LOG\_INFO, LOG\_PRINT\_DOMAIN, "styledString",
            "Before: %{public}zu, After: %{public}zu, Equal: %{public}d", dataSize, resultSize, equal);
        free(buf2);
    }
    free(buf1);

    // 释放描述符
    OH\_ArkUI\_StyledString\_Descriptor\_Destroy(desc);
}

#### 销毁对象

Text组件不对本文涉及的任何对象的生命周期进行管理，需由开发者自行负责。字体引擎接口均配有相应的销毁方法。

OH\_Drawing\_DestroyTextStyle(OH\_Drawing\_TextStyle \*style)：销毁文本样式对象。

OH\_Drawing\_DestroyTypographyStyle(OH\_Drawing\_TypographyStyle \*style)：销毁段落样式对象。

当Text组件仍在界面上显示时，此时释放会导致文字无法绘制。在实际业务场景下需确保Text组件不再使用时才释放。

相关字体引擎销毁的接口请参考[OH\_Drawing\_DestroyTextStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_destroytextstyle) 和 [OH\_Drawing\_DestroyTypographyStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-text-typography-h#oh_drawing_destroytypographystyle)。

Text组件提供[OH\_ArkUI\_StyledString\_Destroy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-styled-string-h#oh_arkui_styledstring_destroy)，用于销毁属性字符串对象。