• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 属性字符串(StyledString/MutableStyledString2
3属性字符串StyledString/MutableStyledString(其中MutableStyledString继承自StyledString,下文统称为StyledString),可用于在字符或段落级别上设置文本样式。将StyledString应用到文本组件上,可以采用多种方式修改文本,包括调整字号、添加字体颜色、使文本具备可点击性,以及通过自定义方式绘制文本等。具体使用方法请参考[属性字符串](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#属性字符串)的文档。
4
5属性字符串提供多种类型样式对象,涵盖各种常见的文本样式格式,例如文本装饰线样式、文本行高样式、文本阴影样式等。也可以自行创建CustomSpan,以应用自定义样式。
6
7## 创建并应用StyledString和MutableStyledString
8
9  可以通过TextController提供的[setStyledString](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#setstyledstring12)方法,将属性字符串附加到文本组件,并推荐在[onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow)或者文本组件的[onAppear](../reference/apis-arkui/arkui-ts/ts-universal-events-show-hide.md#onappear)回调中触发绑定。
10  > **说明:**
11  >
12  > 在aboutToAppear中调用setStyledString方法时,由于该方法运行阶段组件尚未完成创建并成功挂载节点树,因此无法在页面初始化时显示属性字符串。
13  >
14  > 从API version 15开始,在aboutToAppear中调用setStyledString方法,在页面初始化时可以显示属性字符串。
15
16  ```ts
17  @Entry
18  @Component
19  struct styled_string_demo1 {
20    styledString1: StyledString = new StyledString("运动45分钟");
21    mutableStyledString1: MutableStyledString = new MutableStyledString("运动35分钟");
22    controller1: TextController = new TextController();
23    controller2: TextController = new TextController();
24
25    async onPageShow() {
26      // 在生命周期onPageShow回调中绑定属性字符串
27      this.controller1.setStyledString(this.styledString1);
28    }
29
30    build() {
31      Column() {
32        // 显示属性字符串
33        Text(undefined, { controller: this.controller1 })
34        Text(undefined, { controller: this.controller2 })
35          .onAppear(() => {
36            // 在组件onAppear回调中绑定属性字符串
37            this.controller2.setStyledString(this.mutableStyledString1);
38          })
39      }
40      .width('100%')
41    }
42  }
43  ```
44  ![StyledString_Init](figures/span_string_init.png)
45
46## 设置文本样式
47
48属性字符串目前提供了[TextStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#textstyle)、[TextShadowStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#textshadowstyle)、[DecorationStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#decorationstyle)、[BaselineOffsetStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#baselineoffsetstyle)、[LineHeightStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#lineheightstyle)、[LetterSpacingStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#letterspacingstyle)各种Style对象来实现设置文本的各类样式。
49
50- 创建及应用文本字体样式对象(TextStyle)
51
52  ```ts
53  import { LengthMetrics } from '@kit.ArkUI';
54
55  @Entry
56  @Component
57  struct styled_string_demo2 {
58    textStyleAttrs: TextStyle =
59      new TextStyle({ fontWeight: FontWeight.Bolder, fontSize: LengthMetrics.vp(24), fontStyle: FontStyle.Italic });
60    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟 目标达成", [
61      {
62        start: 2,
63        length: 2,
64        styledKey: StyledStringKey.FONT,
65        styledValue: this.textStyleAttrs
66      },
67      {
68        start: 7,
69        length: 4,
70        styledKey: StyledStringKey.FONT,
71        styledValue: new TextStyle({ fontColor: Color.Orange, fontSize: LengthMetrics.vp(12) })
72      }
73    ]);
74    controller: TextController = new TextController();
75
76    async onPageShow() {
77      this.controller.setStyledString(this.mutableStyledString);
78    }
79
80    build() {
81      Column() {
82        // 显示属性字符串
83        Text(undefined, { controller: this.controller })
84          .margin({ top: 10 })
85      }
86      .width('100%')
87    }
88  }
89  ```
90  ![StyledString_TextStyle](figures/StyledString_TextStyle.png)
91
92- 创建及应用文本阴影对象(TextShadowStyle)
93
94  ```ts
95  // xxx.ets
96  @Entry
97  @Component
98  struct styled_string_demo3 {
99    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [
100      {
101        start: 0,
102        length: 3,
103        styledKey: StyledStringKey.TEXT_SHADOW,
104        styledValue: new TextShadowStyle({
105          radius: 5,
106          type: ShadowType.COLOR,
107          color: Color.Red,
108          offsetX: 10,
109          offsetY: 10
110        })
111      }
112    ]);
113    controller: TextController = new TextController();
114
115    async onPageShow() {
116      this.controller.setStyledString(this.mutableStyledString);
117    }
118
119    build() {
120      Column() {
121        // 显示属性字符串
122        Text(undefined, { controller: this.controller })
123      }
124      .width('100%')
125    }
126  }
127  ```
128  ![StyledString_TextShadow](figures/styled_string_text_shadow.png)
129
130- 创建及应用文本装饰线对象(DecorationStyle)
131
132  ```ts
133  // xxx.ets
134  @Entry
135  @Component
136  struct styled_string_demo4 {
137    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [
138      {
139        start: 0,
140        length: 3,
141        styledKey: StyledStringKey.DECORATION,
142        styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Red })
143      }
144    ]);
145    controller: TextController = new TextController();
146
147    async onPageShow() {
148      this.controller.setStyledString(this.mutableStyledString);
149    }
150
151    build() {
152      Column() {
153        // 显示属性字符串
154        Text(undefined, { controller: this.controller })
155      }
156      .width('100%')
157    }
158  }
159  ```
160  ![StyledString_Decoration](figures/styled_string_decoration.png)
161
162- 创建及应用文本基线偏移量对象(BaselineOffsetStyle)
163
164  ```ts
165  import { LengthMetrics } from '@kit.ArkUI';
166
167  // xxx.ets
168  @Entry
169  @Component
170  struct styled_string_demo5 {
171    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [
172      {
173        start: 0,
174        length: 3,
175        styledKey: StyledStringKey.BASELINE_OFFSET,
176        styledValue: new BaselineOffsetStyle(LengthMetrics.px(20))
177      }
178    ]);
179    controller: TextController = new TextController();
180
181    async onPageShow() {
182      this.controller.setStyledString(this.mutableStyledString);
183    }
184
185    build() {
186      Column() {
187        // 显示属性字符串
188        Text(undefined, { controller: this.controller })
189      }
190      .width('100%')
191    }
192  }
193  ```
194  ![StyledString_Baseline](figures/styled_string_baselineoffset.png)
195
196- 创建及应用文本行高对象(LineHeightStyle)
197
198  ```ts
199  import { LengthMetrics } from '@kit.ArkUI';
200
201  // xxx.ets
202  @Entry
203  @Component
204  struct styled_string_demo6 {
205    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟\n顶顶顶\n得到", [
206      {
207        start: 8,
208        length: 3,
209        styledKey: StyledStringKey.LINE_HEIGHT,
210        styledValue: new LineHeightStyle(LengthMetrics.vp(50))
211      }
212    ]);
213    controller: TextController = new TextController();
214
215    async onPageShow() {
216      this.controller.setStyledString(this.mutableStyledString);
217    }
218
219    build() {
220      Column() {
221        // 显示属性字符串
222        Text(undefined, { controller: this.controller })
223      }
224      .width('100%')
225      .margin({ top: 10 })
226    }
227  }
228  ```
229  ![StyledString_lineHeight](figures/styled_string_lineHeight.png)
230
231- 创建及应用文本字符间距对象(LetterSpacingStyle)
232
233  ```ts
234  import { LengthMetrics, LengthUnit } from '@kit.ArkUI';
235
236  // xxx.ets
237  @Entry
238  @Component
239  struct styled_string_demo7 {
240    mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [
241      {
242        start: 0,
243        length: 2,
244        styledKey: StyledStringKey.LETTER_SPACING,
245        styledValue: new LetterSpacingStyle(new LengthMetrics(20, LengthUnit.VP))
246      }
247    ]);
248    controller: TextController = new TextController();
249
250    async onPageShow() {
251      this.controller.setStyledString(this.mutableStyledString);
252    }
253
254    build() {
255      Column() {
256        // 显示属性字符串
257        Text(undefined, { controller: this.controller })
258      }
259      .width('100%')
260    }
261  }
262  ```
263  ![StyledString_letterSpacing](figures/styled_string_letterspacing.png)
264
265## 设置段落样式
266
267可通过[ParagraphStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#paragraphstyle)设置段落样式布局。下图显示了如何分割文本中的段落,段落以换行符 \n 结尾。
268
269![paragraphs](figures/styledstringParagraphs.png)
270
271以下代码示例展示了如何创建ParagraphStyle并应用。如果将ParagraphStyle附加到段落开头末尾或之间的任何位置,均会应用样式,非段落区间内则不会应用样式。
272
273  ```ts
274  import { LengthMetrics } from '@kit.ArkUI';
275  titleParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center });
276  //段落首行缩进15vp
277  paragraphStyleAttr1: ParagraphStyle = new ParagraphStyle({ textIndent: LengthMetrics.vp(15) });
278  //行高样式对象
279  lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24));
280  //创建含段落样式的对象paragraphStyledString1
281  paragraphStyledString1: MutableStyledString = new MutableStyledString("段落标题\n正文第一段落开始0123456789正文第一段落结束。", [
282    {
283      start: 0,
284      length: 4,
285      styledKey: StyledStringKey.PARAGRAPH_STYLE,
286      styledValue: this.titleParagraphStyleAttr
287    },
288    {
289      start: 0,
290      length: 4,
291      styledKey: StyledStringKey.LINE_HEIGHT,
292      styledValue: new LineHeightStyle(new LengthMetrics(50))
293    },{
294    start: 0,
295    length: 4,
296    styledKey: StyledStringKey.FONT,
297    styledValue: new TextStyle({ fontSize: LengthMetrics.vp(24), fontWeight: FontWeight.Bolder })
298  },
299    {
300      start: 5,
301      length: 3,
302      styledKey: StyledStringKey.PARAGRAPH_STYLE,
303      styledValue: this.paragraphStyleAttr1
304    },
305    {
306      start: 5,
307      length: 20,
308      styledKey: StyledStringKey.LINE_HEIGHT,
309      styledValue: this.lineHeightStyle1
310    }
311  ]);
312  ```
313
314  除了可以在创建属性字符串时就预设样式,也可以后续通过[replaceStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#replacestyle)清空原样式替换新样式,同时需要在附加的文本组件controller上主动触发更新绑定的属性字符串。
315
316  ```ts
317  import { LengthMetrics } from '@kit.ArkUI';
318  //段落不设置缩进配置最大行数及超长显示方式
319  paragraphStyleAttr3: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.End, maxLines: 1, wordBreak: WordBreak.BREAK_ALL, overflow: TextOverflow.Ellipsis});
320  // 后续某个节点触发更新段落样式
321  controller: TextController = new TextController();
322  this.paragraphStyledString1.replaceStyle({
323    start: 5,
324    length: 3,
325    styledKey: StyledStringKey.PARAGRAPH_STYLE,
326    styledValue: this.paragraphStyleAttr3
327  });
328  this.controller.setStyledString(this.paragraphStyledString1);
329  ```
330
331## 使用图片
332
333可通过[ImageAttachment](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#imageattachment)来添加图片。
334
335以下示例展示了如何将图片和文本附加到同一个MutableStyledString对象上,并实现图文混排。
336
337  ```ts
338  // xxx.ets
339  import { image } from '@kit.ImageKit';
340  import { LengthMetrics } from '@kit.ArkUI';
341
342  @Entry
343  @Component
344  struct styled_string_demo4 {
345    @State message: string = 'Hello World';
346    imagePixelMap: image.PixelMap | undefined = undefined;
347    @State imagePixelMap3: image.PixelMap | undefined = undefined;
348    mutableStr: MutableStyledString = new MutableStyledString('123');
349    controller: TextController = new TextController();
350    mutableStr2: MutableStyledString = new MutableStyledString('This is set decoration line style to the mutableStr2', [{
351      start: 0,
352      length: 15,
353      styledKey: StyledStringKey.DECORATION,
354      styledValue: new DecorationStyle({
355        type: TextDecorationType.Overline,
356        color: Color.Orange,
357        style: TextDecorationStyle.DOUBLE
358      })
359    }]);
360
361    async aboutToAppear() {
362      console.info("aboutToAppear initial imagePixelMap");
363      this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sea'));
364    }
365
366    private async getPixmapFromMedia(resource: Resource) {
367      let unit8Array = await this.getUIContext().getHostContext()?.resourceManager?.getMediaContent({
368        bundleName: resource.bundleName,
369        moduleName: resource.moduleName,
370        id: resource.id
371      });
372      let imageSource = image.createImageSource(unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength));
373      let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
374        desiredPixelFormat: image.PixelMapFormat.RGBA_8888
375      });
376      await imageSource.release();
377      return createPixelMap;
378    }
379
380    leadingMarginValue: ParagraphStyle = new ParagraphStyle({ leadingMargin: LengthMetrics.vp(5)});
381    //行高样式对象
382    lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24));
383    //Bold样式
384    boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold });
385    //创建含段落样式的对象paragraphStyledString1
386    paragraphStyledString1: MutableStyledString = new MutableStyledString("\n品牌相纸 高清冲印30张\n限时直降5.15元 限量增送", [
387      {
388        start: 0,
389        length: 28,
390        styledKey: StyledStringKey.PARAGRAPH_STYLE,
391        styledValue: this.leadingMarginValue
392      },
393      {
394        start: 14,
395        length: 9,
396        styledKey: StyledStringKey.FONT,
397        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: '#B22222' })
398      },
399      {
400        start: 24,
401        length: 4,
402        styledKey: StyledStringKey.FONT,
403        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontWeight: FontWeight.Lighter })
404      },
405      {
406        start: 11,
407        length: 4,
408        styledKey: StyledStringKey.LINE_HEIGHT,
409        styledValue: this.lineHeightStyle1
410      }
411    ]);
412    paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥16.21 3000+人好评", [
413      {
414        start: 0,
415        length: 5,
416        styledKey: StyledStringKey.PARAGRAPH_STYLE,
417        styledValue: this.leadingMarginValue
418      },
419      {
420        start: 0,
421        length: 4,
422        styledKey: StyledStringKey.LINE_HEIGHT,
423        styledValue: new LineHeightStyle(new LengthMetrics(60))
424      },
425      {
426        start: 0,
427        length: 7,
428        styledKey: StyledStringKey.FONT,
429        styledValue: this.boldTextStyle
430      },
431      {
432        start: 1,
433        length: 1,
434        styledKey: StyledStringKey.FONT,
435        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) })
436      },
437      {
438        start: 2,
439        length: 2,
440        styledKey: StyledStringKey.FONT,
441        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(36) })
442      },
443      {
444        start: 4,
445        length: 3,
446        styledKey: StyledStringKey.FONT,
447        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20) })
448      },
449      {
450        start: 7,
451        length: 9,
452        styledKey: StyledStringKey.FONT,
453        styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)})
454      }
455    ]);
456
457    build() {
458      Row() {
459        Column({ space: 10 }) {
460          Text(undefined, { controller: this.controller })
461            .copyOption(CopyOptions.InApp)
462            .draggable(true)
463            .backgroundColor('#FFFFFF')
464            .borderRadius(5)
465
466          Button('点击查看商品卡片')
467            .onClick(() => {
468              if (this.imagePixelMap !== undefined) {
469                this.mutableStr = new MutableStyledString(new ImageAttachment({
470                  value: this.imagePixelMap,
471                  size: { width: 180, height: 160 },
472                  verticalAlign: ImageSpanAlignment.BASELINE,
473                  objectFit: ImageFit.Fill
474                }));
475                this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2);
476                this.mutableStr.appendStyledString(this.paragraphStyledString1);
477                this.controller.setStyledString(this.mutableStr);
478              }
479            })
480        }
481        .width('100%')
482      }
483      .height('100%')
484      .backgroundColor('#F8F8FF')
485    }
486  }
487  ```
488  ![StyledString_ImageAttachment](figures/StyledStringImageAttachment.png)
489
490## 设置事件
491
492可通过[GestureStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#gesturestyle)设置onClick、onLongPress事件来使文本响应点击长按事件。
493
494除了初始化属性字符串对象即初始样式对象,亦可通过[setStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#setstyle)接口再叠加新样式或更新已有样式,同时需要在附加的文本组件controller上主动触发更新绑定的属性字符串。
495
496  ```ts
497  import { drawing } from '@kit.ArkGraphics2D';
498
499  let gUIContext: UIContext;
500
501  class MyCustomSpan extends CustomSpan {
502    constructor(word: string, width: number, height: number, fontSize: number) {
503      super();
504      this.word = word;
505      this.width = width;
506      this.height = height;
507      this.fontSize = fontSize;
508    }
509
510    onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics {
511      return { width: this.width, height: this.height };
512    }
513
514    onDraw(context: DrawContext, options: CustomSpanDrawInfo) {
515      let canvas = context.canvas;
516
517      const brush = new drawing.Brush();
518      brush.setColor({
519        alpha: 255,
520        red: 0,
521        green: 0,
522        blue: 0
523      });
524      const font = new drawing.Font();
525      font.setSize(gUIContext.vp2px(this.fontSize));
526      const textBlob =
527        drawing.TextBlob.makeFromString(this.word.substring(0, 5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8);
528      canvas.attachBrush(brush);
529
530      this.onDrawRectByRadius(context, options.x, options.x + gUIContext.vp2px(this.width), options.lineTop,
531        options.lineBottom, 20);
532      brush.setColor({
533        alpha: 255,
534        red: 255,
535        green: 255,
536        blue: 255
537      });
538      canvas.attachBrush(brush);
539      canvas.drawTextBlob(textBlob, options.x, options.lineBottom - 30);
540      brush.setColor({
541        alpha: 255,
542        red: 255,
543        green: 228,
544        blue: 196
545      });
546      canvas.attachBrush(brush);
547      const textBlob1 =
548        drawing.TextBlob.makeFromString(this.word.substring(5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8);
549      canvas.drawTextBlob(textBlob1, options.x + gUIContext.vp2px(100), options.lineBottom - 30);
550
551      canvas.detachBrush();
552    }
553
554    onDrawRectByRadius(context: DrawContext, left: number, right: number, top: number, bottom: number, radius: number) {
555      let canvas = context.canvas;
556      let path = new drawing.Path();
557
558      // 画带radius的rect
559      path.moveTo(left + radius, top);
560      path.lineTo(right - radius, top);
561      path.arcTo(right - 2 * radius, top, right, top + 2 * radius, 270, 90);
562      path.lineTo(right, bottom - radius);
563      path.arcTo(right - 2 * radius, bottom - 2 * radius, right, bottom, 0, 90);
564
565      path.lineTo(left + 2 * radius, bottom);
566      path.arcTo(left, bottom - 2 * radius, left + 2 * radius, bottom, 90, 90);
567      path.lineTo(left, top + 2 * radius);
568      path.arcTo(left, top, left + 2 * radius, top + 2 * radius, 180, 90);
569
570      canvas.drawPath(path);
571    }
572
573    setWord(word: string) {
574      this.word = word;
575    }
576
577    width: number = 160;
578    word: string = "drawing";
579    height: number = 10;
580    fontSize: number = 16;
581  }
582
583  @Entry
584  @Component
585  struct styled_string_demo6 {
586    customSpan3: MyCustomSpan = new MyCustomSpan("99VIP88%off", 200, 40, 30);
587    textStyle: MutableStyledString = new MutableStyledString("123");
588    textController: TextController = new TextController();
589    isPageShow: boolean = true;
590
591    aboutToAppear() {
592      gUIContext = this.getUIContext();
593    }
594
595    async onPageShow() {
596      if (!this.isPageShow) {
597        return;
598      }
599      this.isPageShow = false;
600      this.textController.setStyledString(new StyledString(this.customSpan3));
601    }
602
603    build() {
604      Row() {
605        Column() {
606          Text(undefined, { controller: this.textController })
607            .copyOption(CopyOptions.InApp)
608            .fontSize(30)
609        }
610        .width('100%')
611      }
612      .height('100%')
613    }
614  }
615  ```
616![CustomSpanDemo](figures/StyledString_CustomSpan_Scene.PNG)
617
618## 格式转换
619
620可以通过[toHtml](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#tohtml14)、[fromHtml](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#fromhtml)接口实现属性字符串与HTML格式字符串的相关转换,当前支持转换的HTML标签范围:\<p>、\<span>、\<img>。
621
622以下示例展示了如何将属性字符串转换成HTML格式,并展示了如何从HTML格式转换回属性字符串。
623```ts
624// xxx.ets
625import { image } from '@kit.ImageKit';
626import { LengthMetrics } from '@kit.ArkUI';
627
628@Entry
629@Component
630struct styled_string_demo8 {
631  imagePixelMap: image.PixelMap | undefined = undefined
632  @State html : string | undefined = undefined
633  @State styledString : StyledString | undefined = undefined
634  controller1 : TextController = new TextController
635  controller2 : TextController = new TextController
636
637  async aboutToAppear() {
638    console.info("aboutToAppear initial imagePixelMap")
639    this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.icon'))
640  }
641
642  private async getPixmapFromMedia(resource: Resource) {
643    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({
644      bundleName: resource.bundleName,
645      moduleName: resource.moduleName,
646      id: resource.id
647    })
648    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength))
649    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
650      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
651    })
652    await imageSource.release()
653    return createPixelMap
654  }
655
656  build() {
657    Column() {
658      Text(undefined, { controller: this.controller1 }).height(100)
659      Row() {
660        Button("添加属性字符串").onClick(() => {
661          let mutableStyledString1: MutableStyledString = new MutableStyledString("属性字符串", [{
662            start: 0,
663            length: 6,
664            styledKey: StyledStringKey.FONT,
665            styledValue: new TextStyle({ fontColor: Color.Green, fontSize: LengthMetrics.px(50) })
666          }]);
667          if (this.imagePixelMap !== undefined) {
668            let mutableStyledString2 = new MutableStyledString(new ImageAttachment({
669              value: this.imagePixelMap,
670              size: { width: 50, height: 50 },
671            }))
672            mutableStyledString1.appendStyledString(mutableStyledString2)
673          }
674          this.styledString = mutableStyledString1
675          this.controller1.setStyledString(mutableStyledString1)
676        }).margin(5)
677        Button("toHtml").onClick(() => {
678          this.html = StyledString.toHtml(this.styledString)
679        }).margin(5)
680        Button("fromHtml").onClick(async () => {
681          let styledString = await StyledString.fromHtml(this.html)
682          this.controller2.setStyledString(styledString)
683        }).margin(5)
684      }
685      Text(undefined, { controller: this.controller2 }).height(100)
686      Text(this.html)
687    }.width("100%")
688  }
689}
690```
691
692![](figures/styled_string_html.gif)
693
694## 场景示例
695
696该示例通过ParagraphStyle、LineHeightStyle、TextStyle对象展示了会员过期提示的效果。
697
698```ts
699import { LengthMetrics } from '@kit.ArkUI';
700
701@Entry
702@Component
703struct Index {
704  alignCenterParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center });
705  //行高样式对象
706  lineHeightStyle1: LineHeightStyle = new LineHeightStyle(LengthMetrics.vp(24));
707  //Bold样式
708  boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold });
709  //创建含段落样式的对象paragraphStyledString1
710  paragraphStyledString1: MutableStyledString =
711    new MutableStyledString("您的豪华钻石已过期1天\n续费可继续享受会员专属权益", [
712      {
713        start: 0,
714        length: 4,
715        styledKey: StyledStringKey.PARAGRAPH_STYLE,
716        styledValue: this.alignCenterParagraphStyleAttr
717      },
718      {
719        start: 0,
720        length: 4,
721        styledKey: StyledStringKey.LINE_HEIGHT,
722        styledValue: new LineHeightStyle(LengthMetrics.vp(40))
723      },
724      {
725        start: 11,
726        length: 14,
727        styledKey: StyledStringKey.FONT,
728        styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: Color.Grey })
729      },
730      {
731        start: 11,
732        length: 4,
733        styledKey: StyledStringKey.PARAGRAPH_STYLE,
734        styledValue: this.alignCenterParagraphStyleAttr
735      },
736      {
737        start: 11,
738        length: 4,
739        styledKey: StyledStringKey.LINE_HEIGHT,
740        styledValue: this.lineHeightStyle1
741      }
742    ]);
743  paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥4.88¥15", [
744    {
745      start: 0,
746      length: 4,
747      styledKey: StyledStringKey.PARAGRAPH_STYLE,
748      styledValue: this.alignCenterParagraphStyleAttr
749    },
750    {
751      start: 0,
752      length: 4,
753      styledKey: StyledStringKey.LINE_HEIGHT,
754      styledValue: new LineHeightStyle(LengthMetrics.vp(60))
755    },
756    {
757      start: 0,
758      length: 6,
759      styledKey: StyledStringKey.FONT,
760      styledValue: this.boldTextStyle
761    },
762    {
763      start: 1,
764      length: 1,
765      styledKey: StyledStringKey.FONT,
766      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) })
767    },
768    {
769      start: 2,
770      length: 4,
771      styledKey: StyledStringKey.FONT,
772      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(40) })
773    },
774    {
775      start: 6,
776      length: 3,
777      styledKey: StyledStringKey.FONT,
778      styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14) })
779    },
780    {
781      start: 6,
782      length: 3,
783      styledKey: StyledStringKey.DECORATION,
784      styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Grey })
785    }
786  ]);
787  paragraphStyledString3: MutableStyledString = new MutableStyledString("\n02时06分后将失去该优惠", [
788    {
789      start: 0,
790      length: 4,
791      styledKey: StyledStringKey.PARAGRAPH_STYLE,
792      styledValue: this.alignCenterParagraphStyleAttr
793    },
794    {
795      start: 0,
796      length: 4,
797      styledKey: StyledStringKey.LINE_HEIGHT,
798      styledValue: new LineHeightStyle(LengthMetrics.vp(30))
799    },
800    {
801      start: 1,
802      length: 2,
803      styledKey: StyledStringKey.FONT,
804      styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold })
805    },
806    {
807      start: 4,
808      length: 2,
809      styledKey: StyledStringKey.FONT,
810      styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold })
811    }
812  ]);
813  controller: TextController = new TextController();
814
815  build() {
816    Row() {
817      Column({ space: 5 }) {
818        Text(undefined, { controller: this.controller })
819          .width(240)
820          .copyOption(CopyOptions.InApp)
821          .draggable(true)
822          .onAppear(() => {
823            this.paragraphStyledString2.appendStyledString(this.paragraphStyledString3);
824            this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2);
825            this.controller.setStyledString(this.paragraphStyledString1);
826          })
827
828        Button("限时4.88元 立即续费")
829          .width(200)
830          .fontColor(Color.White)
831          .fontSize(18)
832          .backgroundColor('#3CB371')
833          .margin({ bottom: 10 })
834      }
835      .borderWidth(1).borderColor('#FFDEAD')
836      .margin({ left: 10 })
837    }
838    .height('60%')
839  }
840}
841```
842![StyledString_SceneDemo](figures/styledString_sceneDemo.png)
843