1# Styled String (StyledString/MutableStyledString) 2 3Styled strings, implemented by **StyledString** or **MutableStyledString** (collectively referred to as **StyledString**, with **MutableStyledString** inheriting from **StyledString**), are powerful markup objects designed to set text styles at the character or paragraph level. By binding a **StyledString** object to a text component, you can modify the text in various ways, including changing the font size, adding font colors, making the text clickable, and customizing the drawing of text, among others. For details, see [Styled String](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md). 4 5Styled strings provide a variety of style objects that cover various common text formatting styles, such as text decorative lines, line height, and text shadows. You can also create **CustomSpan** objects to apply custom styles. 6 7## Creating and Applying a StyledString Object 8 9 You can bind a **StyledString** object to a text component using the [setStyledString](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#setstyledstring12) API provided by **TextController**. You are advised to call the API in the [onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow) callback for immediate display of the styled string text content. 10 > **NOTE** 11 > 12 > Avoid calling the **setStyledString** API in **aboutToAppear**, as the component may have not yet been mounted to the node tree at the time **aboutToAppear** is executed, preventing the styled string text content from appearing upon page load. 13 14 ```ts 15 @Entry 16 @Component 17 struct styled_string_demo1 { 18 styledString1: StyledString = new StyledString("45-minute workout"); 19 mutableStyledString1: MutableStyledString = new MutableStyledString("35-minute workout"); 20 controller1: TextController = new TextController(); 21 controller2: TextController = new TextController(); 22 23 async onPageShow() { 24 this.controller1.setStyledString(this.styledString1) 25 this.controller2.setStyledString(this.mutableStyledString1) 26 } 27 28 build() { 29 Column() { 30 // Display the styled string. 31 Text(undefined, { controller: this.controller1 }) 32 Text(undefined, { controller: this.controller2 }) 33 } 34 .width('100%') 35 } 36 } 37 ``` 38  39 40## Setting the Text Style 41 42Styled strings offer multiple style objects, such as [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), and [LetterSpacingStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#letterspacingstyle), for setting text styles. 43 44- Creating and applying a **TextStyle** object 45 46 ```ts 47 import { LengthMetrics } from '@kit.ArkUI' 48 @Entry 49 @Component 50 struct styled_string_demo2 { 51 textStyleAttrs: TextStyle = new TextStyle({ fontWeight: FontWeight.Bolder, fontSize: LengthMetrics.vp(24), fontStyle: FontStyle.Italic }) 52 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout goal achieved", [ 53 { 54 start: 2, 55 length: 2, 56 styledKey: StyledStringKey.FONT, 57 styledValue: this.textStyleAttrs 58 }, 59 { 60 start: 7, 61 length: 4, 62 styledKey: StyledStringKey.FONT, 63 styledValue: new TextStyle({ fontColor: Color.Orange, fontSize: LengthMetrics.vp(12)}) 64 } 65 ]); 66 controller: TextController = new TextController(); 67 68 async onPageShow() { 69 this.controller.setStyledString(this.mutableStyledString) 70 } 71 72 build() { 73 Column() { 74 // Display the styled string. 75 Text(undefined, { controller: this.controller }) 76 .margin({ top: 10 }) 77 } 78 .width('100%') 79 } 80 } 81 ``` 82  83 84- Creating and applying a **TextShadowStyle** object 85 86 ```ts 87 // xxx.ets 88 @Entry 89 @Component 90 struct styled_string_demo3 { 91 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout", [ 92 { 93 start: 0, 94 length: 3, 95 styledKey: StyledStringKey.TEXT_SHADOW, 96 styledValue: new TextShadowStyle({ 97 radius: 5, 98 type: ShadowType.COLOR, 99 color: Color.Red, 100 offsetX: 10, 101 offsetY: 10 102 }) 103 } 104 ]); 105 controller: TextController = new TextController(); 106 107 async onPageShow() { 108 this.controller.setStyledString(this.mutableStyledString) 109 } 110 111 build() { 112 Column() { 113 // Display the styled string. 114 Text(undefined, { controller: this.controller }) 115 } 116 .width('100%') 117 } 118 } 119 ``` 120  121 122- Creating and applying a **Text DecorationStyle** object 123 124 ```ts 125 // xxx.ets 126 @Entry 127 @Component 128 struct styled_string_demo4 { 129 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout", [ 130 { 131 start: 0, 132 length: 3, 133 styledKey: StyledStringKey.DECORATION, 134 styledValue: new DecorationStyle({type: TextDecorationType.LineThrough, color: Color.Red}) 135 } 136 ]); 137 controller: TextController = new TextController(); 138 139 async onPageShow() { 140 this.controller.setStyledString(this.mutableStyledString) 141 } 142 143 build() { 144 Column() { 145 // Display the styled string. 146 Text(undefined, { controller: this.controller }) 147 } 148 .width('100%') 149 } 150 } 151 ``` 152  153 154- Creating and applying a **Text BaselineOffsetStyle** object 155 156 ```ts 157 import { LengthMetrics, LengthUnit } from '@kit.ArkUI' 158 // xxx.ets 159 @Entry 160 @Component 161 struct styled_string_demo5 { 162 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout", [ 163 { 164 start: 0, 165 length: 3, 166 styledKey: StyledStringKey.BASELINE_OFFSET, 167 styledValue: new BaselineOffsetStyle(LengthMetrics.px(20)) 168 } 169 ]); 170 controller: TextController = new TextController(); 171 172 async onPageShow() { 173 this.controller.setStyledString(this.mutableStyledString) 174 } 175 176 build() { 177 Column() { 178 // Display the styled string. 179 Text(undefined, { controller: this.controller }) 180 } 181 .width('100%') 182 } 183 } 184 ``` 185  186 187- Creating and applying a **LineHeightStyle** object 188 189 ```ts 190 import { LengthMetrics, LengthUnit } from '@kit.ArkUI' 191 // xxx.ets 192 @Entry 193 @Component 194 struct styled_string_demo6 { 195 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout\nFighting\nAchieved", [ 196 { 197 start: 8, 198 length: 3, 199 styledKey: StyledStringKey.LINE_HEIGHT, 200 styledValue: new LineHeightStyle(LengthMetrics.vp(50)) 201 } 202 ]); 203 controller: TextController = new TextController(); 204 205 async onPageShow() { 206 this.controller.setStyledString(this.mutableStyledString) 207 } 208 209 build() { 210 Column() { 211 // Display the styled string. 212 Text(undefined, { controller: this.controller }) 213 } 214 .width('100%') 215 .margin({ top: 10 }) 216 } 217 } 218 ``` 219  220 221- Creating and applying a **LetterSpacingStyle** object 222 223 ```ts 224 import { LengthMetrics, LengthUnit } from '@kit.ArkUI' 225 // xxx.ets 226 @Entry 227 @Component 228 struct styled_string_demo7 { 229 mutableStyledString: MutableStyledString = new MutableStyledString("35-minute workout", [ 230 { 231 start: 0, 232 length: 2, 233 styledKey: StyledStringKey.LETTER_SPACING, 234 styledValue: new LetterSpacingStyle(new LengthMetrics(20, LengthUnit.VP)) 235 } 236 ]); 237 controller: TextController = new TextController(); 238 239 async onPageShow() { 240 this.controller.setStyledString(this.mutableStyledString) 241 } 242 243 build() { 244 Column() { 245 // Display the styled string. 246 Text(undefined, { controller: this.controller }) 247 } 248 .width('100%') 249 } 250 } 251 ``` 252  253 254## Setting the Paragraph Style 255 256You can set the paragraph style using [ParagraphStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#paragraphstyle). The figure below shows how to divide paragraphs in the text, with each paragraph ending with a newline character \n. 257 258 259 260The following example shows how to create and apply a paragraph style. The style is applied to the start, end or any position within a paragraph; it does not apply to non-paragraph areas. 261 262 ```ts 263 import { LengthMetrics } from '@kit.ArkUI' 264 titleParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center }); 265 // Create a paragraph style for a 15 vp first-line text indent. 266 paragraphStyleAttr1: ParagraphStyle = new ParagraphStyle({ textIndent: LengthMetrics.vp(15) }); 267 // Line height style object 268 lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24)); 269 // Create a paragraph style object paragraphStyledString1. 270 paragraphStyledString1: MutableStyledString = new MutableStyledString("Paragraph Title\nFirst paragraph starts 0123456789 First paragraph ends.", [ 271 { 272 start: 0, 273 length: 4, 274 styledKey: StyledStringKey.PARAGRAPH_STYLE, 275 styledValue: this.titleParagraphStyleAttr 276 }, 277 { 278 start: 0, 279 length: 4, 280 styledKey: StyledStringKey.LINE_HEIGHT, 281 styledValue: new LineHeightStyle(new LengthMetrics(50)) 282 },{ 283 start: 0, 284 length: 4, 285 styledKey: StyledStringKey.FONT, 286 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(24), fontWeight: FontWeight.Bolder }) 287 }, 288 { 289 start: 5, 290 length: 3, 291 styledKey: StyledStringKey.PARAGRAPH_STYLE, 292 styledValue: this.paragraphStyleAttr1 293 }, 294 { 295 start: 5, 296 length: 20, 297 styledKey: StyledStringKey.LINE_HEIGHT, 298 styledValue: this.lineHeightStyle1 299 } 300 ]); 301 ``` 302 303 In addition to presetting styles when creating a styled string, you can also clear the original styles and replace them with new ones later using the [replaceStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#replacestyle) API. After the replacement, you need to proactively trigger an update to the bound styled string on the attached text component's controller. 304 305 ```ts 306 import { LengthMetrics } from '@kit.ArkUI' 307 // Set the maximum number of lines and text overflow mode for the paragraph, without setting the indent. 308 paragraphStyleAttr3: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.End, maxLines: 1, wordBreak: WordBreak.BREAK_ALL, overflow: TextOverflow.Ellipsis}); 309 // Later in the code, trigger an update to the paragraph style. 310 controller: TextController = new TextController(); 311 this.paragraphStyledString1.replaceStyle({ 312 start: 5, 313 length: 3, 314 styledKey: StyledStringKey.PARAGRAPH_STYLE, 315 styledValue: this.paragraphStyleAttr3 316 }) 317 this.controller.setStyledString(this.paragraphStyledString1) 318 ``` 319 320## Using Images 321 322You can add images using [ImageAttachment](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#imageattachment). 323 324The following example shows how to attach images and text to the same **MutableStyledString** object for mixed display of text and images. 325 326 ```ts 327 // xxx.ets 328 import { image } from '@kit.ImageKit' 329 import { LengthMetrics } from '@kit.ArkUI' 330 331 @Entry 332 @Component 333 struct styled_string_demo4 { 334 @State message: string = 'Hello World' 335 imagePixelMap: image.PixelMap | undefined = undefined 336 @State imagePixelMap3: image.PixelMap | undefined = undefined 337 mutableStr: MutableStyledString = new MutableStyledString('123'); 338 controller: TextController = new TextController(); 339 mutableStr2: MutableStyledString = new MutableStyledString('This is set decoration line style to the mutableStr2', [{ 340 start: 0, 341 length: 15, 342 styledKey: StyledStringKey.DECORATION, 343 styledValue: new DecorationStyle({ 344 type: TextDecorationType.Overline, 345 color: Color.Orange, 346 style: TextDecorationStyle.DOUBLE 347 }) 348 }]) 349 350 async aboutToAppear() { 351 console.info("aboutToAppear initial imagePixelMap") 352 this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sea')) 353 } 354 355 private async getPixmapFromMedia(resource: Resource) { 356 let unit8Array = await this.getUIContext().getHostContext()?.resourceManager?.getMediaContent({ 357 bundleName: resource.bundleName, 358 moduleName: resource.moduleName, 359 id: resource.id 360 }) 361 let imageSource = image.createImageSource(unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength)) 362 let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ 363 desiredPixelFormat: image.PixelMapFormat.RGBA_8888 364 }) 365 await imageSource.release() 366 return createPixelMap 367 } 368 369 leadingMarginValue: ParagraphStyle = new ParagraphStyle({ leadingMargin: LengthMetrics.vp(5)}) 370 // Line height style object 371 lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24)); 372 //Bold style 373 boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold }); 374 // Create a paragraph style object paragraphStyledString1. 375 paragraphStyledString1: MutableStyledString = new MutableStyledString("\n30 HD prints\nCYN5.15 off Limited offer", [ 376 { 377 start: 0, 378 length: 28, 379 styledKey: StyledStringKey.PARAGRAPH_STYLE, 380 styledValue: this.leadingMarginValue 381 }, 382 { 383 start: 14, 384 length: 9, 385 styledKey: StyledStringKey.FONT, 386 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: '#B22222' }) 387 }, 388 { 389 start: 24, 390 length: 4, 391 styledKey: StyledStringKey.FONT, 392 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontWeight: FontWeight.Lighter }) 393 }, 394 { 395 start: 11, 396 length: 4, 397 styledKey: StyledStringKey.LINE_HEIGHT, 398 styledValue: this.lineHeightStyle1 399 } 400 ]); 401 paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥16.21 3000+ reviews", [ 402 { 403 start: 0, 404 length: 5, 405 styledKey: StyledStringKey.PARAGRAPH_STYLE, 406 styledValue: this.leadingMarginValue 407 }, 408 { 409 start: 0, 410 length: 4, 411 styledKey: StyledStringKey.LINE_HEIGHT, 412 styledValue: new LineHeightStyle(new LengthMetrics(60)) 413 }, 414 { 415 start: 0, 416 length: 7, 417 styledKey: StyledStringKey.FONT, 418 styledValue: this.boldTextStyle 419 }, 420 { 421 start: 1, 422 length: 1, 423 styledKey: StyledStringKey.FONT, 424 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) }) 425 }, 426 { 427 start: 2, 428 length: 2, 429 styledKey: StyledStringKey.FONT, 430 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(36) }) 431 }, 432 { 433 start: 4, 434 length: 3, 435 styledKey: StyledStringKey.FONT, 436 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20) }) 437 }, 438 { 439 start: 7, 440 length: 9, 441 styledKey: StyledStringKey.FONT, 442 styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)}) 443 } 444 ]) 445 446 build() { 447 Row() { 448 Column({ space: 10 }) { 449 Text(undefined, { controller: this.controller }) 450 .copyOption(CopyOptions.InApp) 451 .draggable(true) 452 .backgroundColor('#FFFFFF') 453 .borderRadius(5) 454 455 Button('View Product Details') 456 .onClick(() => { 457 if (this.imagePixelMap !== undefined) { 458 this.mutableStr = new MutableStyledString(new ImageAttachment({ 459 value: this.imagePixelMap, 460 size: { width: 180, height: 160 }, 461 verticalAlign: ImageSpanAlignment.BASELINE, 462 objectFit: ImageFit.Fill 463 })) 464 this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2) 465 this.mutableStr.appendStyledString(this.paragraphStyledString1) 466 this.controller.setStyledString(this.mutableStr) 467 } 468 }) 469 } 470 .width('100%') 471 } 472 .height('100%') 473 .backgroundColor('#F8F8FF') 474 } 475 } 476 ``` 477  478 479## Setting Events 480 481You can use [GestureStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#gesturestyle) to set up **onClick** and **onLongPress** events to enable text to respond to click and long-press actions. 482 483In addition to initializing styled strings with initial style objects, you can also use the [setStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#setstyle) API to overlay new styles or update existing ones. After making changes, you need to manually trigger an update of the bound styled string on the attached text component's controller. 484 485 ```ts 486import { drawing } from '@kit.ArkGraphics2D'; 487 488class MyCustomSpan extends CustomSpan { 489 constructor(word: string, width: number, height: number, fontSize: number) { 490 super(); 491 this.word = word; 492 this.width = width; 493 this.height = height; 494 this.fontSize = fontSize; 495 } 496 497 onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics { 498 return { width: this.width, height: this.height } 499 } 500 501 onDraw(context: DrawContext, options: CustomSpanDrawInfo) { 502 let canvas = context.canvas; 503 504 const brush = new drawing.Brush(); 505 brush.setColor({ alpha: 255, red: 0, green: 0, blue: 0 }) 506 const font = new drawing.Font() 507 font.setSize(vp2px(this.fontSize)) 508 const textBlob = drawing.TextBlob.makeFromString(this.word.substring(0, 5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8) 509 canvas.attachBrush(brush) 510 511 this.onDrawRectByRadius(context, options.x, options.x + vp2px(this.width), options.lineTop, options.lineBottom, 20) 512 brush.setColor({ alpha: 255, red: 255, green: 255, blue: 255 }) 513 canvas.attachBrush(brush) 514 canvas.drawTextBlob(textBlob, options.x, options.lineBottom - 30) 515 brush.setColor({ alpha: 255, red: 255, green: 228 , blue: 196 }) 516 canvas.attachBrush(brush) 517 const textBlob1 = drawing.TextBlob.makeFromString(this.word.substring(5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8) 518 canvas.drawTextBlob(textBlob1, options.x + vp2px(100), options.lineBottom - 30) 519 520 canvas.detachBrush() 521 } 522 onDrawRectByRadius(context: DrawContext, left: number, right: number, top: number, bottom: number, radius: number) { 523 let canvas = context.canvas 524 let path = new drawing.Path() 525 526 // Draw a rectangle with rounded corners. 527 path.moveTo(left + radius, top) 528 path.lineTo(right - radius, top) 529 path.arcTo(right - 2 * radius, top, right, top + 2 * radius, 270, 90) 530 path.lineTo(right, bottom - radius) 531 path.arcTo(right - 2 * radius, bottom - 2 * radius, right, bottom, 0, 90) 532 533 path.lineTo(left + 2 * radius, bottom) 534 path.arcTo(left, bottom - 2 * radius, left + 2 * radius, bottom, 90, 90) 535 path.lineTo(left, top + 2 * radius) 536 path.arcTo(left, top, left + 2 * radius, top + 2 * radius, 180, 90) 537 538 canvas.drawPath(path) 539 } 540 setWord(word: string) { 541 this.word = word; 542 } 543 544 width: number = 160 545 word: string = "drawing" 546 height: number = 10 547 fontSize: number = 16 548} 549 550@Entry 551@Component 552struct styled_string_demo6 { 553 customSpan3: MyCustomSpan = new MyCustomSpan("99VIP88%off", 200, 40, 30) 554 textStyle: MutableStyledString = new MutableStyledString("123"); 555 textController: TextController = new TextController() 556 isPageShow: boolean = true 557 558 async onPageShow() { 559 if (!this.isPageShow) { 560 return 561 } 562 this.isPageShow = false 563 this.textController.setStyledString(new StyledString(this.customSpan3)) 564 } 565 566 build() { 567 Row() { 568 Column() { 569 Text(undefined, { controller: this.textController }) 570 .copyOption(CopyOptions.InApp) 571 .fontSize(30) 572 } 573 .width('100%') 574 } 575 .height('100%') 576 } 577} 578 ``` 579 580 581## Example 582 583This example shows how to implement an expired membership notification using **ParagraphStyle**, **LineHeightStyle**, and **TextStyle** objects. 584 585```ts 586import { LengthMetrics } from '@kit.ArkUI'; 587 588@Entry 589@Component 590struct Index { 591 alignCenterParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center }); 592 // Line height style object 593 lineHeightStyle1: LineHeightStyle= new LineHeightStyle(LengthMetrics.vp(24)); 594 //Bold style 595 boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold }); 596 // Create a paragraph style object paragraphStyledString1. 597 paragraphStyledString1: MutableStyledString = new MutableStyledString("Diamond Membership expired\nRenew to keep your perks ", [ 598 { 599 start: 0, 600 length: 4, 601 styledKey: StyledStringKey.PARAGRAPH_STYLE, 602 styledValue: this.alignCenterParagraphStyleAttr 603 }, 604 { 605 start: 0, 606 length: 4, 607 styledKey: StyledStringKey.LINE_HEIGHT, 608 styledValue: new LineHeightStyle(LengthMetrics.vp(40)) 609 }, 610 { 611 start: 11, 612 length: 14, 613 styledKey: StyledStringKey.FONT, 614 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: Color.Grey }) 615 }, 616 { 617 start: 11, 618 length: 4, 619 styledKey: StyledStringKey.PARAGRAPH_STYLE, 620 styledValue: this.alignCenterParagraphStyleAttr 621 }, 622 { 623 start: 11, 624 length: 4, 625 styledKey: StyledStringKey.LINE_HEIGHT, 626 styledValue: this.lineHeightStyle1 627 } 628 ]); 629 paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥4.88¥15", [ 630 { 631 start: 0, 632 length: 4, 633 styledKey: StyledStringKey.PARAGRAPH_STYLE, 634 styledValue: this.alignCenterParagraphStyleAttr 635 }, 636 { 637 start: 0, 638 length: 4, 639 styledKey: StyledStringKey.LINE_HEIGHT, 640 styledValue: new LineHeightStyle(LengthMetrics.vp(60)) 641 }, 642 { 643 start: 0, 644 length: 6, 645 styledKey: StyledStringKey.FONT, 646 styledValue: this.boldTextStyle 647 }, 648 { 649 start: 1, 650 length: 1, 651 styledKey: StyledStringKey.FONT, 652 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18)}) 653 }, 654 { 655 start: 2, 656 length: 4, 657 styledKey: StyledStringKey.FONT, 658 styledValue: new TextStyle({ fontSize: LengthMetrics.vp(40)}) 659 }, 660 { 661 start: 6, 662 length: 3, 663 styledKey: StyledStringKey.FONT, 664 styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)}) 665 }, 666 { 667 start: 6, 668 length: 3, 669 styledKey: StyledStringKey.DECORATION, 670 styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Grey }) 671 } 672 ]) 673 paragraphStyledString3: MutableStyledString = new MutableStyledString("\nOffer ends in 02:06", [ 674 { 675 start: 0, 676 length: 4, 677 styledKey: StyledStringKey.PARAGRAPH_STYLE, 678 styledValue: this.alignCenterParagraphStyleAttr 679 }, 680 { 681 start: 0, 682 length: 4, 683 styledKey: StyledStringKey.LINE_HEIGHT, 684 styledValue: new LineHeightStyle(LengthMetrics.vp(30)) 685 }, 686 { 687 start: 1, 688 length: 2, 689 styledKey: StyledStringKey.FONT, 690 styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold }) 691 }, 692 { 693 start: 4, 694 length: 2, 695 styledKey: StyledStringKey.FONT, 696 styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold }) 697 } 698 ]) 699 controller: TextController = new TextController(); 700 701 build() { 702 Row() { 703 Column( { space : 5 }) { 704 Text(undefined, { controller: this.controller }) 705 .width(240) 706 .copyOption(CopyOptions.InApp) 707 .draggable(true) 708 .onAppear(()=>{ 709 this.paragraphStyledString2.appendStyledString(this.paragraphStyledString3) 710 this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2) 711 this.controller.setStyledString(this.paragraphStyledString1) 712 }) 713 714 Button("Renew") 715 .width(200) 716 .fontColor(Color.White) 717 .fontSize(18) 718 .backgroundColor('#3CB371') 719 .margin({ bottom: 10 }) 720 } 721 .borderWidth(1).borderColor('#FFDEAD') 722 .margin({ left: 10 }) 723 } 724 .height('60%') 725 } 726} 727``` 728 729