一、StyledString 到底是什麼?為什麼要用它?

在平常的 UI 裏我們用組件 Text 顯示一段字符串,但它只能控制整段文字的統一樣式。
StyledString 是一種“可帶樣式的數據對象”,用來表示一段文本中不同區間可以擁有不同樣式、事件、段落行為的文本

它的用途比單純的 Text 更強:

  • 文本中部分內容字體、顏色、粗體/斜體不一樣
  • 插入圖片/圖標到文本中(圖文混排)
  • 文本局部可響應點擊或長按事件
  • 不同段落有不同對齊/行高/縮進等規則

説白了:當一個普通的 Text 做不出你想要的“富文本效果”時,就用 StyledString。


二、StyledString 的核心對象和構成

StyledString 有兩個相關類型:

類型

説明

StyledString

不可變的屬性字符串,一旦創建樣式就固定

MutableStyledString

可變屬性字符串,在創建後可以追加、修改樣式

兩者都可以附加到 Text 組件的 TextController 上去渲染


三、基本使用步驟(從無到有)

下面是使用 StyledString 的“完整路線圖”:


Step 1 — 創建 StyledString 或 MutableStyledString

// 如果不需要後續修改樣式,可以直接用 StyledString
let simpleStyled = new StyledString("Hello 富文本 World");

// 如果需要在創建後再追加樣式、文字、圖片
let mutable = new MutableStyledString("Hello Native");

MutableStyledString 繼承自 StyledString,比它更靈活。


Step 2 — 創建 TextController 並設置屬性字符串

需要一個 TextController 綁定到 Text 組件上,然後把 StyledString 通過 setStyledString() 傳給它:

textController: TextController = new TextController();

// 頁面顯示時或 onPageShow 裏綁定屬性字符串
this.textController.setStyledString(mutable);

推薦在頁面顯示生命週期(如 onPageShow)裏設置,否則文本組件可能還沒完全渲染導致樣式不生效


Step 3 — 在 Text 中關聯控制器

Text(undefined, { controller: this.textController })
  .fontSize(16)   // 可以再配合基礎 Text 屬性

這種寫法讓 Text 不直接寫字符串,而是從 TextController 獲取並渲染 StyledString。


四、怎麼設置不同樣式?(屬性對象詳解)

屬性字符串的威力來自於“給文本區間指定不同的樣式對象”。這種機制是用一個由 { start, length, styledKey, styledValue } 對象數組來描述的。


1) 文本樣式 TextStyle

用於設置字體樣式(顏色、粗體/斜體、大小等):

import { TextStyle } from '@kit.ArkUI';

let attrs: TextStyle = new TextStyle({ fontSize: 18, fontColor: Color.Red, fontWeight: FontWeight.Bold });

創建好後,你可以在 MutableStyledString 初始化時綁定:

new MutableStyledString("説明文字", [
  { start: 0, length: 2, styledKey: StyledStringKey.FONT, styledValue: attrs }
]);

同一段文字可以被映射成多個不同風格的區間。


2) 文本陰影 TextShadowStyle

為部分文本加陰影效果,讓文本更有層次感:

import { TextShadowStyle, ShadowType } from '@kit.ArkUI';

new TextShadowStyle({ radius: 4, type: ShadowType.COLOR, color: Color.Gray });

這段陰影效果可以附加到特定區間。x


3) 裝飾線(如刪除線、下劃線) DecorationStyle

裝飾線樣式也可以獨立設置:

new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Gray });

比如把價格中原價塗掉用刪除線展示,就用這個。


4) 段落樣式 ParagraphStyle

如果你的文本里有多個段落(換行 \n),你可以用段落樣式控制文本對齊、縮進、間距等:

import { ParagraphStyle } from '@kit.ArkUI';

let paraStyle = new ParagraphStyle({ textAlign: TextAlign.Center, textIndent: LengthMetrics.vp(15) });

再把這個樣式對象附加到某段區間上


5) 其他樣式(字符間距、基線偏移等)

還包括:

  • BaselineOffsetStyle —— 控制文本基線偏移
  • LineHeightStyle —— 控制單行文本高度
  • LetterSpacingStyle —— 控制字符間距

這些都是更細粒度的文本控制。


五、圖文混排(不是 RichEditor,但很像)

你也可以在屬性字符串中插入圖片:

import { ImageAttachment, ImageFit, ImageSpanAlignment } from '@kit.ArkUI';

new ImageAttachment({
  value: pixelMap,
  size: { width: 100, height: 80 },
  verticalAlign: ImageSpanAlignment.BASELINE,
  objectFit: ImageFit.Fill
});

然後 append 到現有的屬性字符串裏,實現圖、文字混合顯示

真實項目多見於商品卡片中“圖 + 文並排又不想單獨用 Row/Column”場景。


六、事件/交互文本

屬性字符串還能讓文本具備可點擊區域並響應事件:

import { GestureStyle } from '@kit.ArkUI';

let clickStyle = new GestureStyle({
  onClick: () => promptAction.showToast({ message: "點擊了文本片段" })
});

再把這種 GestureStyle 綁定在特定區間內,就實現了“文本某個字可響應點擊”。


七、真項目裏怎麼用?幾個真實例子


場景 1:讓一段話裏一部分文字變色強調

let discountText = new MutableStyledString
  { start: 3, length: 2, styledKey: StyledStringKey.FONT,
    styledValue: new TextStyle({ fontColor: Color.Red, fontWeight: FontWeight.Bold }) }
]);

這種寫法比多個 Text 組件拼更清爽、維護也更簡單x


場景 2:商品原價和折扣價 Text 裏只給原價加刪除線

let styledPrice = new MutableStyledString("原價 ¥199 現價 ¥99", [
  { start: 3, length: 6, styledKey: StyledStringKey.DECORATION,
    styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Gray }) }
]);

在單個 Text 控件裏搞定比拆成兩個 Text 視覺更一致


場景 3:標題 + 副標題不同樣式混合

let titleSentence = new MutableStyledString("主題標題\n副標題説明", [
  { start: 0, length: 5, styledKey: StyledStringKey.FONT,
    styledValue: new TextStyle({ fontSize: LengthMetrics.vp(24), fontWeight: FontWeight.Bold }) },
  { start: 6, length: 4, styledKey: StyledStringKey.FONT,
    styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: Color.Gray }) }
]);

這種控制段落級別文本樣式的寫法,在大標題 + 小説明裏特別常用


八、容易踩的坑


. 屬性字符串不會自動繼承 Text 屬性

屬性字符串本身帶樣式,不會自動繼承 Text 外層設置的基礎屬性,比如 Text.fontSize(),要在 StyledString 中明確寫出來。


2. 索引從 0 開始,容易算錯區間

數組裏每條樣式定義都有 startlength,必須確保這些值不會越界,否則可能導致樣式疊加錯位。


3. 刷新屬性字符串後要重新 setStyledString

如果你修改了 MutableStyledString 的樣式(append/replaceStyle),需要重新執行:

textController.setStyledString(mutableStyledString);

才會觸發 UI 更新,否則不會生效。