当前位置: 首页 > news >正文

鸿蒙文本组件高级特性——富文本属性字符串

1、概 述

属性字符串StyledString/MutableStyledString(MutableStyledString继承于StyledString,以下统一简称StyledString)是功能强大的标记对象,可用于字符或段落级别设置文本样式。通过将StyledString附加到文本组件, 可以通过多种方式更改文本,包括修改字号、添加字体颜色、使文本可点击以及自定义方式绘制文本等。

属性字符串提供多种类型样式对象,涵盖各种常见的文本样式格式。也可以自行创建CustomSpan, 以应用自定义样式。

2、富文本属性字符串的使用

👉🏻 基本的创建与使用

可以通过TextController提供的setStyledString(StyledString)方法将属性字符串附加到文本组件【推荐在onPageShow中触发绑定,在aboutToAppear中调用setStyledString无法实现页面初始即可见属性字符串文本内容,因为aboutToAppear运行时组件还没有完成创建并成功挂载节点树】

基本的使用示例如下:

@Entry@Componentstruct styled_string_demo1 {  styledString1: StyledString = new StyledString("运动45分钟");  mutableStyledString1: MutableStyledString = new MutableStyledString("运动35分钟");  controller1: TextController = new TextController();  controller2: TextController = new TextController();  async onPageShow() {    this.controller1.setStyledString(this.styledString1)    this.controller2.setStyledString(this.mutableStyledString1)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller1 })      Text(undefined, { controller: this.controller2 })    }    .width('100%')  }}

示例效果如下(没有设置自定义样式):

图片

👉🏻 设置行内文本样式

属性字符串目前提供了TextStyle、TextShadowStyle、DecorationStyle、BaselineOffsetStyle、LineHeightStyle、LetterSpacingStyle各种Style对象来实现设置文本的各类样式。分别介绍如下:

  • 使用TextStyle设置样式

示例代码如下:

import { LengthMetrics } from '@kit.ArkUI'@Entry@Componentstruct styled_string_demo2 {  textStyleAttrs: TextStyle = new TextStyle({ fontWeight: FontWeight.Bolder, fontSize: LengthMetrics.vp(24), fontStyle: FontStyle.Italic })  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟 目标达成", [    {      start: 2,      length: 2,      styledKey: StyledStringKey.FONT,      styledValue: this.textStyleAttrs    },    {      start: 7,      length: 4,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontColor: Color.Orange, fontSize: LengthMetrics.vp(12)})    }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })        .margin({ top: 10 })    }    .width('100%')  }}

效果如下:

图片

  • 使用TextShadowStyle设置样式

示例代码如下:

// xxx.ets@Entry@Componentstruct styled_string_demo3 {  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [  {    start: 0,    length: 3,    styledKey: StyledStringKey.TEXT_SHADOW,    styledValue: new TextShadowStyle({      radius: 5,      type: ShadowType.COLOR,      color: Color.Red,      offsetX: 10,      offsetY: 10    })  }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })    }    .width('100%')  }}

示例效果如下:

图片

  • 使用DecorationStyle设置样式

示例代码如下:

// xxx.ets@Entry@Componentstruct styled_string_demo4 {  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [  {    start: 0,    length: 3,    styledKey: StyledStringKey.DECORATION,    styledValue: new DecorationStyle({type: TextDecorationType.LineThrough, color: Color.Red})  }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })    }    .width('100%')  }}

示例效果如下:

图片

  • 使用BaselineOffsetStyle设置样式

示例代码如下:

import { LengthMetrics, LengthUnit } from '@kit.ArkUI'// xxx.ets@Entry@Componentstruct styled_string_demo5 {  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [    {      start: 0,      length: 3,      styledKey: StyledStringKey.BASELINE_OFFSET,      styledValue: new BaselineOffsetStyle(LengthMetrics.px(20))    }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })    }    .width('100%')  }}

示例效果如下:

图片

  • 使用LineHeightStyle设置样式

示例代码如下:

import { LengthMetrics, LengthUnit } from '@kit.ArkUI'// xxx.ets@Entry@Componentstruct styled_string_demo6 {  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟\n顶顶顶\n得到", [    {      start: 8,      length: 3,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: new LineHeightStyle(LengthMetrics.vp(50))    }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })    }    .width('100%')    .margin({ top: 10 })  }}

示例效果如下:

图片

  • 使用LetterSpacingStyle设置样式

示例代码如下:

import { LengthMetrics, LengthUnit } from '@kit.ArkUI'// xxx.ets@Entry@Componentstruct styled_string_demo7 {  mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [    {      start: 0,      length: 2,      styledKey: StyledStringKey.LETTER_SPACING,      styledValue: new LetterSpacingStyle(new LengthMetrics(20, LengthUnit.VP))    }  ]);  controller: TextController = new TextController();  async onPageShow() {    this.controller.setStyledString(this.mutableStyledString)  }  build() {    Column() {      // 显示属性字符串      Text(undefined, { controller: this.controller })    }    .width('100%')  }}

示例效果如下:

图片

👉🏻 设置段落样式

可通过ParagraphStyle设置段落样式布局。下图显示了如何分割文本中的段落,段落以换行符 \n 结尾。

图片

下面的代码示例展示了如何创建 ParagraphStyle 并应用。如果将 ParagraphStyle 附加到段落开头末尾或之间的任何位置均会应用样式,非段落区间内则不会应用样式。示例代码如下:​​​​​​​

import { LengthMetrics } from '@kit.ArkUI'titleParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center });//段落首行缩进15vpparagraphStyleAttr1: ParagraphStyle = new ParagraphStyle({ textIndent: LengthMetrics.vp(15) });//创建含段落样式的对象paragraphStyledString1paragraphStyledString1: MutableStyledString = new MutableStyledString("段落标题\n正文第一段落开始0123456789正文第一段落结束。", [  {    start: 0,    length: 4,    styledKey: StyledStringKey.PARAGRAPH_STYLE,    styledValue: this.titleParagraphStyleAttr  },  {    start: 0,    length: 4,    styledKey: StyledStringKey.LINE_HEIGHT,    styledValue: new LineHeightStyle(new LengthMetrics(50))  },{  start: 0,  length: 4,  styledKey: StyledStringKey.FONT,  styledValue: new TextStyle({ fontSize: LengthMetrics.vp(24), fontWeight: FontWeight.Bolder })},  {    start: 5,    length: 3,    styledKey: StyledStringKey.PARAGRAPH_STYLE,    styledValue: this.paragraphStyleAttr1  },  {    start: 5,    length: 20,    styledKey: StyledStringKey.LINE_HEIGHT,    styledValue: this.lineHeightStyle1  }]);

除了可以在创建属性字符串时就预设样式,也可以后续通过replaceStyle清空原样式替换新样式, 同时需要在附加的文本组件controller上主动触发更新绑定的属性字符串。示例代码如下:​​​​​​​

import { LengthMetrics } from '@kit.ArkUI'//段落不设置缩进配置最大行数及超长显示方式paragraphStyleAttr3: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.End, maxLines: 1, wordBreak: WordBreak.BREAK_ALL, overflow: TextOverflow.Ellipsis});// 后续某个节点触发更新段落样式controller: TextController = new TextController();this.paragraphStyledString1.replaceStyle({  start: 5,  length: 3,  styledKey: StyledStringKey.PARAGRAPH_STYLE,  styledValue: this.paragraphStyleAttr3})this.controller.setStyledString(this.mutableStyledString3)

👉🏻 使用图片

可通过ImageAttachment来添加图片。下面的示例展示了如何将图片和文本附加到同一个MutableStyledString对象上,并实现图文混排。​​​​​​​

// xxx.etsimport { image } from '@kit.ImageKit'import { LengthMetrics } from '@kit.ArkUI'@Entry@Componentstruct styled_string_demo4 {  @State message: string = 'Hello World'  imagePixelMap: image.PixelMap | undefined = undefined  @State imagePixelMap3: image.PixelMap | undefined = undefined  mutableStr: MutableStyledString = new MutableStyledString('123');  controller: TextController = new TextController();  mutableStr2: MutableStyledString = new MutableStyledString('This is set decoration line style to the mutableStr2', [{    start: 0,    length: 15,    styledKey: StyledStringKey.DECORATION,    styledValue: new DecorationStyle({      type: TextDecorationType.Overline,      color: Color.Orange,      style: TextDecorationStyle.DOUBLE    })  }])  async aboutToAppear() {    console.info("aboutToAppear initial imagePixelMap")    this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sea'))  }  private async getPixmapFromMedia(resource: Resource) {    let unit8Array = await this.getUIContext().getHostContext()?.resourceManager?.getMediaContent({      bundleName: resource.bundleName,      moduleName: resource.moduleName,      id: resource.id    })    let imageSource = image.createImageSource(unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength))    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({      desiredPixelFormat: image.PixelMapFormat.RGBA_8888    })    await imageSource.release()    return createPixelMap  }  leadingMarginValue: ParagraphStyle = new ParagraphStyle({ leadingMargin: LengthMetrics.vp(5)})  //行高样式对象  lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24));  //Bold样式  boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold });  //创建含段落样式的对象paragraphStyledString1  paragraphStyledString1: MutableStyledString = new MutableStyledString("\n品牌相纸 高清冲印30张\n限时直降5.15元 限量增送", [    {      start: 0,      length: 28,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.leadingMarginValue    },    {      start: 14,      length: 9,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: '#B22222' })    },    {      start: 24,      length: 4,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontWeight: FontWeight.Lighter })    },    {      start: 11,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: this.lineHeightStyle1    }  ]);  paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥16.21 3000+人好评", [    {      start: 0,      length: 5,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.leadingMarginValue    },    {      start: 0,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: new LineHeightStyle(new LengthMetrics(60))    },    {      start: 0,      length: 7,      styledKey: StyledStringKey.FONT,      styledValue: this.boldTextStyle    },    {      start: 1,      length: 1,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) })    },    {      start: 2,      length: 2,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(36) })    },    {      start: 4,      length: 3,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20) })    },    {      start: 7,      length: 9,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)})    }  ])  build() {    Row() {      Column({ space: 10 }) {        Text(undefined, { controller: this.controller })          .copyOption(CopyOptions.InApp)          .draggable(true)          .backgroundColor('#FFFFFF')          .borderRadius(5)        Button('点击查看商品卡片')          .onClick(() => {            if (this.imagePixelMap !== undefined) {              this.mutableStr = new MutableStyledString(new ImageAttachment({                value: this.imagePixelMap,                size: { width: 180, height: 160 },                verticalAlign: ImageSpanAlignment.BASELINE,                objectFit: ImageFit.Fill              }))              this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2)              this.mutableStr.appendStyledString(this.paragraphStyledString1)              this.controller.setStyledString(this.mutableStr)            }          })      }      .width('100%')    }    .height('100%')    .backgroundColor('#F8F8FF')  }}

示例效果如下:

图片

👉🏻 设置事件

可通过GestureStyle设置onClick、onLongPress事件来使文本响应点击长按事件。除了初始化属性字符串对象即初始样式对象,还可以可通过setStyle接口再叠加新样式或更新已有样式,同时需要在附加的文本组件controller上主动触发更新绑定的属性字符串。示例代码如下:​​​​​​​

import { drawing } from '@kit.ArkGraphics2D';class MyCustomSpan extends CustomSpan {constructor(word: string, width: number, height: number, fontSize: number) {  super();  this.word = word;  this.width = width;  this.height = height;  this.fontSize = fontSize;}onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics {  return { width: this.width, height: this.height }}onDraw(context: DrawContext, options: CustomSpanDrawInfo) {  let canvas = context.canvas;  const brush = new drawing.Brush();  brush.setColor({ alpha: 255, red: 0, green: 0, blue: 0 })  const font = new drawing.Font()  font.setSize(vp2px(this.fontSize))  const textBlob = drawing.TextBlob.makeFromString(this.word.substring(0, 5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8)  canvas.attachBrush(brush)  this.onDrawRectByRadius(context, options.x, options.x + vp2px(this.width), options.lineTop, options.lineBottom, 20)  brush.setColor({ alpha: 255, red: 255, green: 255, blue: 255 })  canvas.attachBrush(brush)  canvas.drawTextBlob(textBlob, options.x, options.lineBottom - 30)  brush.setColor({ alpha: 255, red: 255, green: 228 , blue: 196 })  canvas.attachBrush(brush)  const textBlob1 = drawing.TextBlob.makeFromString(this.word.substring(5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8)  canvas.drawTextBlob(textBlob1, options.x + vp2px(100), options.lineBottom - 30)  canvas.detachBrush()}onDrawRectByRadius(context: DrawContext, left: number, right: number, top: number, bottom: number, radius: number) {  let canvas = context.canvas  let path = new drawing.Path()  // 画带radius的rect  path.moveTo(left  + radius, top)  path.lineTo(right - radius, top)  path.arcTo(right - 2 * radius, top, right, top + 2 * radius, 270, 90)  path.lineTo(right, bottom - radius)  path.arcTo(right - 2 * radius, bottom - 2 * radius, right, bottom, 0, 90)  path.lineTo(left + 2 * radius, bottom)  path.arcTo(left, bottom - 2 * radius, left + 2 * radius, bottom, 90, 90)  path.lineTo(left, top + 2 * radius)  path.arcTo(left, top, left + 2 * radius, top + 2 * radius, 180, 90)  canvas.drawPath(path)}setWord(word: string) {  this.word = word;}width: number = 160word: string = "drawing"height: number = 10fontSize: number = 16}@Entry@Componentstruct styled_string_demo6 {customSpan3: MyCustomSpan = new MyCustomSpan("99VIP88%off", 200, 40, 30)textStyle: MutableStyledString = new MutableStyledString("123");textController: TextController = new TextController()isPageShow: boolean = trueasync onPageShow() {  if (!this.isPageShow) {    return  }  this.isPageShow = false  this.textController.setStyledString(new StyledString(this.customSpan3))}build() {  Row() {    Column() {      Text(undefined, { controller: this.textController })        .copyOption(CopyOptions.InApp)        .fontSize(30)    }    .width('100%')  }  .height('100%')}}

示例效果如下:

图片

3、一个综合实例

实现一个富文本效果,效果如下:

图片

实现代码如下:​​​​​​​

import { LengthMetrics } from '@kit.ArkUI';@Entry@Componentstruct Index {  alignCenterParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center });  //行高样式对象  lineHeightStyle1: LineHeightStyle= new LineHeightStyle(LengthMetrics.vp(24));  //Bold样式  boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold });  //创建含段落样式的对象paragraphStyledString1  paragraphStyledString1: MutableStyledString = new MutableStyledString("您的豪华钻石已过期1天\n续费可继续享受会员专属权益", [    {      start: 0,      length: 4,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.alignCenterParagraphStyleAttr    },    {      start: 0,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: new LineHeightStyle(LengthMetrics.vp(40))    },    {      start: 11,      length: 14,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: Color.Grey })    },    {      start: 11,      length: 4,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.alignCenterParagraphStyleAttr    },    {      start: 11,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: this.lineHeightStyle1    }  ]);  paragraphStyledString2: MutableStyledString = new MutableStyledString("\n¥4.88¥15", [    {      start: 0,      length: 4,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.alignCenterParagraphStyleAttr    },    {      start: 0,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: new LineHeightStyle(LengthMetrics.vp(60))    },    {      start: 0,      length: 6,      styledKey: StyledStringKey.FONT,      styledValue: this.boldTextStyle    },    {      start: 1,      length: 1,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18)})    },    {      start: 2,      length: 4,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(40)})    },    {      start: 6,      length: 3,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)})    },    {      start: 6,      length: 3,      styledKey: StyledStringKey.DECORATION,      styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Grey })    }  ])  paragraphStyledString3: MutableStyledString = new MutableStyledString("\n02时06分后将失去该优惠", [    {      start: 0,      length: 4,      styledKey: StyledStringKey.PARAGRAPH_STYLE,      styledValue: this.alignCenterParagraphStyleAttr    },    {      start: 0,      length: 4,      styledKey: StyledStringKey.LINE_HEIGHT,      styledValue: new LineHeightStyle(LengthMetrics.vp(30))    },    {      start: 1,      length: 2,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold })    },    {      start: 4,      length: 2,      styledKey: StyledStringKey.FONT,      styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold })    }  ])  controller: TextController = new TextController();  build() {    Row() {      Column( { space : 5 }) {        Text(undefined, { controller: this.controller })          .width(240)          .copyOption(CopyOptions.InApp)          .draggable(true)          .onAppear(()=>{            this.paragraphStyledString2.appendStyledString(this.paragraphStyledString3)            this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2)            this.controller.setStyledString(this.paragraphStyledString1)          })        Button("限时4.88元 立即续费")          .width(200)          .fontColor(Color.White)          .fontSize(18)          .backgroundColor('#3CB371')          .margin({ bottom: 10 })      }      .borderWidth(1).borderColor('#FFDEAD')      .margin({ left: 10 })    }    .height('60%')  }}


http://www.mrgr.cn/news/59809.html

相关文章:

  • spygalss cdc 检测的bug(二)
  • php后端学习,Java转php
  • Kubernetes运行大数据组件-制作镜像
  • 创建匿名管道
  • 影刀RPA实战:常见实用功能指令
  • Linux命令笔记
  • Python记录-字典
  • 设计模式(二)
  • ROM修改进阶教程------简单通过指令来修改系统安全设置中选项的的开启或者关闭 内置指令在rom中的应用
  • 从零实现数据结构:一文搞定所有排序!(下集)
  • 网络文件系统nfs实验1
  • 基于neo4j关系图谱的协同过滤科研推荐系统
  • 工具方法 - Omnifocus: 网页版基本操作
  • 软考:软件建模的抽象级别
  • 解读AVL树:平衡二叉搜索树的奥秘
  • hdlbits系列verilog解答(DFF8-8位D触发器)-81
  • android openGL ES详解——缓冲区VBO/VAO/EBO/FBO/离屏渲染
  • 高速大容量还自带原厂数据恢复服务,希捷睿翼4TB移动硬盘评测
  • Python酷库之旅-第三方库Pandas(170)
  • css-画一个三角形
  • JavaFx -- chapter05(多用户服务器)
  • 基于Python的B站视频数据分析与可视化
  • 什么是环境变量?如何安装JAVA环境变量,实现命令行(cmd)执行java命令?win11、win10、win7一篇文章带你全部解决!包教包会!
  • 【论文笔记】Perceiver: General Perception with Iterative Attention
  • 【次小生成树】
  • 十八、【智能体】数据库:未来科技的大脑