1. HarmonyOS 文本显示 (Text/Span)

  Text是文本组件,通常用于展示用户视图,如显示文章的文字。
  官方API@ohos.measure (文本计算)

1.1. Text/Span

  Text可通过string字符串来、引用Resource资源创建,Span只能作为Text和RichEditor组件的子组件显示文本内容。可以在一个Text内添加多个Span来显示一段信息,例如产品说明书、承诺书等。Span组件需要写到Text组件内,单独写Span组件不会显示信息,Text与Span同时配置文本内容时,Span内容覆盖Text内容

Text('我是Text') {
  Span('我是Span')
}
.padding(10)
.borderWidth(1)
import { CustomTextSpan } from '../../components/common/CustomTextSpan';
import { router } from '@kit.ArkUI';
import { TitleBar } from '../../components/common/TitleBar';
import { RouterParams } from '@zzsKit/zzsLib';

@Entry
@Component
struct TextPage {
  @State pageTitle: string = "点击事件"
  @State text: string = '点击事件'

  aboutToAppear() {
    try {
      this.pageTitle = (router
        .getParams() as RouterParams).title
    } catch (e) {
    }
  }

  build() {
    Column() {
      TitleBar({ pageTitle: $pageTitle })
      CustomTextSpan({
        content: `简介:长海,海拔3060公尺,长约五公里,宽约六百多公尺,面积达到93万平方公尺。长海旁边的山峰终年积雪,四周森林珠翠,站在长海观台上看去,蓝天白云,皑皑峰雪尽收眼底,感觉山和天互相连接在一起,没有距离,这也是长海.`,
        fontSize: 12,
        fontColor: "#000000",
        btnFontColor: "#007FFF",
        totalMargin: 28, // totalMargin= margin两边的距离 14+14
        callback: {
          isShow: (isShow: boolean) => {
            // 不需要展开的话可做自己的业务
            // return !isShow // 不需要展开
            // 如果需要展开 return <isShow> 即可
            return isShow
          }
        }
      }).margin({ left: 14, right: 14 })


      Column() {
        Row() {
          Text("1").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })
          Text("我是热搜词条1")
            .fontSize(12)
            .fontColor(Color.Blue)
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .fontWeight(300)
          Text("爆")
            .margin({ left: 6 })
            .textAlign(TextAlign.Center)
            .fontSize(10)
            .fontColor(Color.White)
            .fontWeight(600)
            .backgroundColor(0x770100)
            .borderRadius(5)
            .width(15)
            .height(14)
        }.width('100%').margin(5)

        Row() {
          Text("2").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })
          Text("我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2")
            .fontSize(12)
            .fontColor(Color.Blue)
            .fontWeight(300)
            .constraintSize({ maxWidth: 200 })
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
          Text("热")
            .margin({ left: 6 })
            .textAlign(TextAlign.Center)
            .fontSize(10)
            .fontColor(Color.White)
            .fontWeight(600)
            .backgroundColor(0xCC5500)
            .borderRadius(5)
            .width(15)
            .height(14)
        }.width('100%').margin(5)

        Row() {
          Text("3").fontSize(14).fontColor(Color.Orange).margin({ left: 10, right: 10 })
          Text("我是热搜词条3")
            .fontSize(12)
            .fontColor(Color.Blue)
            .fontWeight(300)
            .maxLines(1)
            .constraintSize({ maxWidth: 200 })
            .textOverflow({ overflow: TextOverflow.Ellipsis })
          Text("热")
            .margin({ left: 6 })
            .textAlign(TextAlign.Center)
            .fontSize(10)
            .fontColor(Color.White)
            .fontWeight(600)
            .backgroundColor(0xCC5500)
            .borderRadius(5)
            .width(15)
            .height(14)
        }.width('100%').margin(5)

        Row() {
          Text("4").fontSize(14).fontColor(Color.Grey).margin({ left: 10, right: 10 })
          Text("我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4")
            .fontSize(12)
            .fontColor(Color.Blue)
            .fontWeight(300)
            .constraintSize({ maxWidth: 200 })
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
        }.width('100%').margin(5)
      }.width('100%')
    }
    .height('100%')
    .width('100%')
  }
}

在这里插入图片描述

1.2. 字符串<展开/收起>

在这里插入图片描述
在这里插入图片描述

1.2.2. 方式一

measure.measureTextSize
跟方式二使用一样,只是API调用不同,可仔细查看官网

1.2.3. 方式二(API 12+)


import { display, promptAction } from '@kit.ArkUI'
import { MeasureUtils } from '@ohos.arkui.UIContext';


interface CustomTextSpanInterface {
  isShow?: (isShow: boolean) => boolean;
}

@Component
export struct CustomTextSpan {
  @State maxLines: number = 1
  // 临时内容,用于计算
  @State contentTemp: string = ''
  // 折叠时 显示内容
  @State showContent: string = ''
  // 是否展开
  @State isShow: boolean = false
  @Prop fontSize: number
  @Prop btnFontColor: number | string = Color.Blue
  @Prop fontColor: number | string = '#000000'
  // 原始内容
  @Prop @Watch('getContent') content: string = ''
  // 屏幕宽度  vp
  @State w: number = -1
  // vp 
  @Prop totalMargin: number = 0
  @State measureUtils: MeasureUtils = this.getUIContext().getMeasureUtils();
  @State computeHeight: SizeOptions = this.measureUtils.measureTextSize({
    textContent: this.content
  })
  @State computeLine: SizeOptions = this.measureUtils.measureTextSize({
    textContent: this.content
  })
  callback?: CustomTextSpanInterface

  getContent() {
    this.contentTemp = this.content
    let temp = display.getDefaultDisplaySync().width
    this.w = px2vp(temp) - this.totalMargin
    this.computeHeight = this.measureUtils.measureTextSize({
      textContent: this.content,
      constraintWidth: this.w,
      fontSize: this.fontSize
    })
    this.computeLine = this.measureUtils.measureTextSize({
      textContent: this.content,
      constraintWidth: this.w,
      fontSize: this.fontSize,
      maxLines: this.maxLines
    })
    this.compute()
  }

  compute() {
    while (Number(this.computeHeight.height) > Number(this.computeLine.height)) {
      // 通过循环,每次减少一个字符长度,重新计算,直到高度满足要求
      this.contentTemp = this.contentTemp.substring(0, this.contentTemp.length - 1);
      this.computeHeight = this.measureUtils.measureTextSize({
        textContent: this.contentTemp + '...' + ' 展开', // <按钮文字>也要放入进行计算
        constraintWidth: this.w,
        fontSize: this.fontSize
      });
      this.showContent = this.contentTemp + '...'
    }
  }

  build() {
    Column() {
      if (!this.isShow) {
        Text() {
          Span(`${this.showContent}`).fontColor(this.fontColor)
          Span("展开").onClick(() => {
            // 如果只是展开收起改变下值就行
            // this.isShow = !this.isShow

            // 真实项目,不需要展开而是需要一个弹窗  所以自定义回调 可以通过返回的boolean 控制 需要 展开还是弹窗
            if (this.callback) {
              this.isShow = this.callback?.isShow!(true)
            }
          }).fontColor(this.btnFontColor)
        }.width('100%').fontSize(this.fontSize)
      }
      if (this.isShow) {
        Text(this.content).width('100%').fontSize(this.fontSize).fontColor(this.fontColor)
        Text("收起")
          .width('100%')
          .onClick(() => {
            // this.isShow = !this.isShow
            if (this.callback) {
              this.isShow = this.callback?.isShow!(false)
            }
          })
          .width('100%')
          .textAlign(TextAlign.End)
          .fontColor(this.btnFontColor)
          .fontSize(this.fontSize)
      }
    }.width('100%')
  }
}

使用:

import { CustomTextSpan } from '../../components/common/CustomTextSpan';

@Entry
@Component
struct TextPage {
  @State message: string = 'Hello World';

  build() {
    Column() {
      CustomTextSpan({
        content: `简介:长海,海拔3060公尺,长约五公里,宽约六百多公尺,面积达到93万平方公尺。长海旁边的山峰终年积雪,四周森林珠翠,站在长海观台上看去,蓝天白云,皑皑峰雪尽收眼底,感觉山和天互相连接在一起,没有距离,这也是长海.`,
        fontSize: 12,
        fontColor: "#000000",
        btnFontColor: "#007FFF",
        totalMargin: 28,// totalMargin= margin两边的距离 14+14
        callback: {
          isShow: (isShow: boolean) => {
            // 不需要展开的话可做自己的业务

            // return !isShow // 不需要展开
            // 如果需要展开 return <isShow> 即可
            return isShow
          }
        }
      }).margin({ left: 14, right: 14 })

    }
    .height('100%')
    .width('100%')
    .padding(30)
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐