HarmonyOS如何实现Text根据对应的字符串改变Text中字符指定颜色?

2025-06-14 15:37:33
107次阅读
0个评论
最后修改时间:2025-06-14 15:37:59

HarmonyOS如何实现Text根据对应的字符串改变Text中字符指定颜色?

前言

大家好,我是青蓝逐码组织的君莫笑。

相信大家在各种项目中多多少少都会遇到一大串字符串中里面有特定的字符需要进行颜色变换以及点击事件,但是官方目前没有找到直接可以用的组件,因此我参考各路大神以及自己理解封装了一个组件,在项目中可以直接使用,并且你可以根据项目需要进行修改拓展。

组件封装

首先为了性能考虑我们使用@Builder代替@Component,为了拓展性以及UI能够动态更新因此我们需要定义一个复杂的数据类型model

数据类型

export class TextModel {
  // 整段字符串
  allText: string = '我是一整段文字哦哦哦哦哦'
  // 需要替换的文字
  changeText: string = '文'
  // 文字大小
  allFontSize: number = 16
  // 替换文字大小
  changeFontSize: number = 12
  // 默认文字颜色
  allFontColor: ResourceStr = '#ff000000'
  // 替换文字颜色
  changeFontColor: ResourceStr = '#ffb32121'
  // 默认点击事件
  OnClick: () => void = () => {
    AlertDialog.show({ message: JSON.stringify('默认点击事件') })
  }
  // 替换颜色的点击事件
  changeOnClick: () => void = () => {
    AlertDialog.show({ message: JSON.stringify('替换颜色的点击事件') })
  }
  // constructor(allText: string, changeText: string, allFontSize: number, changeFontSize: number,
  //   allFontColor: ResourceStr, changeFontColor: ResourceStr, OnClick: () => void, changeOnClick: () => void) {
  //   this.allText = allText
  //   this.changeText = changeText
  //   this.allFontSize = allFontSize
  //   this.changeFontSize = changeFontSize
  //   this.allFontColor = allFontColor
  //   this.changeFontColor = changeFontColor
  //   this.OnClick = OnClick
  //   this.changeOnClick = changeOnClick
  // }
}

说明:

  • 我个人推荐使用clsss代替interface写法,使用类能够更好的进行封装以及拓展
  • 为了demo快速启动,我对构造函数进行了注释,实际项目中可以再进行修改

视图UI

有了数据类型后我们可以开始写最重要的UI部分

@Builder
export function
TextBuilder(textModel: TextModel) {
  Text() {
    ForEach(textModel.allText.split(""), (item: string) => {
      Span(item)
        .fontSize(textModel.changeText.split("").includes(item) ? textModel.changeFontSize : textModel.allFontSize)
        .fontColor(textModel.changeText.split("").includes(item) ? textModel.changeFontColor : textModel.allFontColor)
        .onClick(() => {
          if (textModel.changeText.includes(item)) {
            textModel.changeOnClick()
          } else {
            textModel.OnClick()
          }
        })
    })
  }
}

其中原理就是将一段字符串里的每一个字符进行分割最后形成数组,最后通过includes方法去寻找对应字符进行替换

说明

  • 为什么选择@Builder而不选择@Component?
  • 此处直接cv官网说明## 优先使用@Builder方法代替自定义组件
  • 由于@Builder不涉及生命周期,在自定义组件大量嵌套的场景中,更加轻量级的@Builder在性能方面更加出色。因此,当自定义组件不涉及到状态变量和自定义生命周期时,可以优先使用@Builder替换自定义组件,提升性能。具体的原理与优化案例请参阅优先使用@Builder方法代替自定义组件

开始使用

@Component
export struct TextView {
  @State textModel: TextModel = new TextModel()

  build() {
    Column(){
      TextBuilder(this.textModel)
    }
  }
}

效果

image.png

说明

  • 我在数据类型中增加了构造函数的入口,因此可以随时根据接口返回的数据进行修改
  • 遇到接口返回的是字符串数组怎么办?直接将其拼接为字符串即可,组件内能直接处理
收藏00

登录 后评论。没有帐号? 注册 一个。