HarmonyOS 鸿蒙Next:arkts的UI中text如何高亮文字

发布于 1周前 作者 ionicwang 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:arkts的UI中text如何高亮文字

搜索关键字,关联了一段文本,我需要使用特殊颜色标记文本中的关键字内容,如何实现?
Span组件太麻烦,是否有简单点的方法?

4 回复

可以参考下面方法:


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
 }
}
class DeclareDemo {
 format: string | Resource = ''
 args: CustomSpan[] = []
}

[@Entry](/user/Entry)
[@Component](/user/Component)
struct TextDemoPage {
 urlRegex = /测试一下/g;
 [@State](/user/State) declare: DeclareDemo = {
   format: '',
   args: []
 }
 [@State](/user/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('111111111111---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%')
 }
}

更多关于HarmonyOS 鸿蒙Next:arkts的UI中text如何高亮文字的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


代码封装好方法,调一下就行了,感觉也不是特别麻烦。

参考:https://blog.csdn.net/zhongcongxu01/article/details/142716162

理论上应该就是分词,然后拆分数组,使用span组件包裹标记文本,没有想到其他好办法

在HarmonyOS鸿蒙Next的arkts UI框架中,要实现文字高亮效果,你可以通过以下方式操作:

arkts(Ark UI Toolkit for TS/JS)主要使用TypeScript或JavaScript进行开发,并依赖于ArkUI框架提供的组件和API。对于文本高亮,你可以利用Span组件或自定义绘制来实现。

  1. 使用Span组件:如果高亮部分可以预先确定,你可以使用Span组件来包裹需要高亮的文本,并为其设置不同的样式,如颜色、字体加粗等。例如,创建一个Text组件,并在其中嵌入带有不同样式的Span组件。

  2. 自定义绘制:如果高亮部分需要动态计算,或者你想要实现更复杂的高亮效果,可以通过自定义绘制来实现。你可以继承Canvas组件,并在onDraw方法中实现文本的绘制和高亮逻辑。

  3. 利用样式和主题:在arkts中,你还可以定义和应用全局或局部的样式和主题,这有助于统一管理文本的高亮效果。

请注意,上述方法的具体实现取决于你的应用场景和具体需求。如果你正在开发arkts应用,并遇到实现上的困难,建议查阅最新的HarmonyOS开发文档和arkts API参考。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部