HarmonyOS string占位符中如何使用Span

如何在Text文本显示带有占位符的string,占位符需要变换颜色字体支持点击。

HarmonyOS
2025-01-09 16:54:20
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
aquaa

部分文字实现高亮参考示例:

export enum SpanType {
  normal,
  hyperlink,
}

export class CustomSpan {
  public content: string | Resource
  public type: SpanType
  public event: () => void

  constructor(content: string | Resource, type: SpanType = SpanType.normal, event: () => void = () => {
  }) {
    this.content = content
    this.type = type
    this.event = event
  }

  normal(): CustomSpan {
    this.type = SpanType.normal
    return this
  }

  hyperlink(event: () => void): CustomSpan {
    this.type = SpanType.hyperlink
    this.event = event
    return this
  }
}

export class CustomText {
  public static readonly PLACEHOLDER = new RegExp('(%[1-9]{1}[0-9]{0,}\\$s)')
  public spans: Array<CustomSpan>

  constructor(spans: Array<CustomSpan> = []) {
    this.spans = spans
  }

  append(span: CustomSpan): CustomText {
    this.spans.push(span)
    return this
  }

  appendNormal(text: string | Resource): CustomText {
    this.append(new CustomSpan(text).normal())
    return this
  }

  appendHyperlink(text: string | Resource, onClick: () => void): CustomText {
    this.append(new CustomSpan(text).hyperlink(onClick))
    return this
  }

  format(format: string | Resource, args: Array<CustomSpan> = []): CustomText {
    if (!format || !args || args?.length === 0) {
      this.appendNormal(format)
      return this
    }

    if (typeof format === 'string') {
      if (format.length !== 0) {
        this.resolve(format, args)
      }
    } else {
      try {
        let value: string = getContext(this).resourceManager.getStringSync(format)
        if (value && value.length !== 0) {
          this.resolve(value, args)
        }
      } catch (e) {
        console.warn(`CustomText getStringSync: ${JSON.stringify(format)} exception: ${e}`);
      }
    }
    return this
  }

  private resolve(format: string, args: Array<CustomSpan>): CustomText {
    let length: number = args.length

    format.split(CustomText.PLACEHOLDER).forEach((value: string, index: number) => {
      if (!value.match(CustomText.PLACEHOLDER)) {

        this.appendNormal(value)
        return
      }
      let argIndex: number = Number(value.replace('%', '').replace('$s', '')) - 1
      if (argIndex >= length) {
        return
      }
      let span: CustomSpan = args[argIndex++]
      if (span.type === SpanType.normal) {
        this.appendNormal(span.content)
      } else if (span.type === SpanType.hyperlink) {
        this.appendHyperlink(span.content, span.event)
      }
    })
    return this
  }
}
// TextDemoPage.ets
import { CustomSpan, CustomText, SpanType } from './TestTen';

class DeclareDemo {
  format: string | Resource = ''
  args: CustomSpan[] = []
}

@Entry
@Component
struct TextDemoPage {
  urlRegex = /测试一下/g;
  @State declare: DeclareDemo = {
    format: '',
    args: []
  }
  @State textDeclare: Array<CustomText> = []

  aboutToAppear(): void {
    let text: string = '这是一个示例文本测试一下。哈哈哈哈哈哈哈测试一下 哈哈哈哈哈测试一下'
    let urls = text.match(this.urlRegex)
    let newText: string = text
    if (urls) {
      let args: CustomSpan[] = []
      urls.forEach((url, idx) => {
        newText = newText.replace(url, `%${idx + 1}$s`)
        args.push(new CustomSpan(url).hyperlink(() => {
          console.log('aboutToAppear---url: ', url)
        }),)
      });
      this.declare = {
        format: newText,
        args: args
      }

      this.textDeclare = [new CustomText().format(this.declare.format, this.declare.args)]
      console.log('111 -this.textDeclare: ', JSON.stringify(this.textDeclare))
    }
  }

  build() {
    Row() {
      Column() {
        ForEach(this.textDeclare, (declare: CustomText, index) => {
          Text() {
            ForEach(declare.spans, (span: CustomSpan) => {
              if (span.type == SpanType.normal) {
                Span(span.content)
                  .fontSize(14)
                  .fontColor('#191919')
              } else if (span.type == SpanType.hyperlink) {
                Span(span.content)
                  .fontSize(14)
                  .fontColor('#007dff')
                  .decoration({ type: TextDecorationType.None, color: '#007dff' })
                  .onClick(() => {
                    if (span.event) {
                      span.event()
                    }
                  })
              }
            })
          }
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}
分享
微博
QQ
微信
回复
2025-01-09 19:19:09
相关问题
HarmonyOS是否有string占位
406浏览 • 1回复 待解决
HarmonyOS如何使用Image占位
731浏览 • 1回复 待解决
HarmonyOS span如何设置圆角
708浏览 • 1回复 待解决
ArkTS如何实现空格占位
2572浏览 • 1回复 待解决
HarmonyOS Text/Span使用问题
658浏览 • 1回复 待解决
HarmonyOS image 组件占位
476浏览 • 1回复 待解决
HarmonyOS 使用Text里套Span标签使用问题
717浏览 • 1回复 待解决
HarmonyOS string.json如何定义数组类型
343浏览 • 1回复 待解决
HarmonyOS TextSpan显示问题
781浏览 • 1回复 待解决
HarmonyOS Text的ImageSpan和Span
822浏览 • 1回复 待解决
span组件使用margin属性失效
2184浏览 • 1回复 待解决
HarmonyOS 如何让多语言支持占位
310浏览 • 1回复 待解决