1# 属性字符串(StyledString/MutableStyledString) 2 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  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  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  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  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  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  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  264 265## 设置段落样式 266 267可通过[ParagraphStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#paragraphstyle)设置段落样式布局。下图显示了如何分割文本中的段落,段落以换行符 \n 结尾。 268 269 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  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 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 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 843