一、StyledString 到底是什麼?為什麼要用它?
在平常的 UI 裏我們用組件 Text 顯示一段字符串,但它只能控制整段文字的統一樣式。
StyledString 是一種“可帶樣式的數據對象”,用來表示一段文本中不同區間可以擁有不同樣式、事件、段落行為的文本
它的用途比單純的 Text 更強:
- 文本中部分內容字體、顏色、粗體/斜體不一樣
- 插入圖片/圖標到文本中(圖文混排)
- 文本局部可響應點擊或長按事件
- 不同段落有不同對齊/行高/縮進等規則
説白了:當一個普通的 Text 做不出你想要的“富文本效果”時,就用 StyledString。
二、StyledString 的核心對象和構成
StyledString 有兩個相關類型:
|
類型
|
説明
|
|
|
不可變的屬性字符串,一旦創建樣式就固定
|
|
|
可變屬性字符串,在創建後可以追加、修改樣式
|
兩者都可以附加到 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 開始,容易算錯區間
數組裏每條樣式定義都有 start 和 length,必須確保這些值不會越界,否則可能導致樣式疊加錯位。
3. 刷新屬性字符串後要重新 setStyledString
如果你修改了 MutableStyledString 的樣式(append/replaceStyle),需要重新執行:
textController.setStyledString(mutableStyledString);
才會觸發 UI 更新,否則不會生效。