ArkUI Text:文字排顺了,页面像换了个设计师

举报
蓝瘦的蜕变 发表于 2026/08/15 22:44:57 2026/08/15
【摘要】 今天我们继续把 Text 这篇补完整:不只让文字显示出来,还要让一句话里的重点、小标签、小图标都能自然地排在一起。 页面里最常见的问题不是“没有文字”,而是文字都长一个样。标题不像标题,说明太抢眼,关键字没有重点,小图标还被单独塞进 Row 里,最后越写越乱。 这篇我们只盯文本本身。Text 管整段文字,Span 管局

ArkUI Text:文字排顺了,页面像换了个设计师

今天我们继续把 Text 这篇补完整:不只让文字显示出来,还要让一句话里的重点、小标签、小图标都能自然地排在一起。

页面里最常见的问题不是“没有文字”,而是文字都长一个样。标题不像标题,说明太抢眼,关键字没有重点,小图标还被单独塞进 Row 里,最后越写越乱。

这篇我们只盯文本本身。Text 管整段文字,Span 管局部文字,ImageSpan 管夹在文字里的图片。先把这三个关系捋清楚,后面写列表、卡片、表单时会省很多事。

参考文档:

  • https://developer.huawei.cn/consumer/cn/doc/harmonyos-guides/arkts-common-components-text-display
  • https://developer.huawei.cn/consumer/cn/doc/harmonyos-guides/arkts-text-image-layout
  • https://developer.huawei.cn/consumer/cn/doc/harmonyos-guides/arkui
  • https://developer.huawei.cn/consumer/cn/doc/harmonyos-guides/arkts-ui-development

先把页面骨架放下

案例页面只有一个文件:

  • entry/src/main/ets/pages/arkUI/basic/ArkUITextDemo.ets

开头还是老规矩:一个组件名,一个标题,再用一段轻一点的说明把范围讲清楚。

Text('ArkUI Text')
  .width('100%')
  .fontSize(24)
  .fontWeight(700)
  .fontColor('#0F172A')

Text('今天我们只做一件事:把文字层级调顺。先看字号、颜色、行高、Span、ImageSpan 和截断,别急着往页面里塞更多组件。')
  .width('100%')
  .fontSize(14)
  .fontColor('#64748B')
  .lineHeight(22)

说明文字别写得太黑。它只是帮读者知道下面要看什么,不应该抢走标题的注意力。

字号先把身份分出来

正文和标题不要用同一套字号。能显示是一回事,能不能一眼分清层级是另一回事。

Text('普通正文适合用 14 到 16 的字号,颜色不要太黑。')
  .width('100%')
  .fontSize(15)
  .fontColor('#475569')
  .lineHeight(24)

Text('标题文本要有层级')
  .width('100%')
  .fontSize(20)
  .fontWeight(700)
  .fontColor('#0F172A')

我一般会先把正文压住,别让它黑得像标题。标题再加粗,层级自然就出来了。

颜色别一把梭

同样是文字,主信息、补充说明、风险提示,最好别都一个颜色。

Text('主信息:用户第一眼应该看到这一句')
  .fontSize(16)
  .fontWeight(700)
  .fontColor('#1D4ED8')

Text('次信息:补充说明放轻一点,别和主信息抢注意力')
  .fontSize(14)
  .fontColor('#64748B')

Text('警示信息:颜色可以提醒风险,但不要把整页都染红')
  .fontSize(14)
  .fontWeight(600)
  .fontColor('#B91C1C')

红色不是不能用,但别一出问题就满屏红。只把真正需要提醒的那句标出来就够了。

Span 负责一句话里的重点

如果只是某几个字需要加粗、换色、加背景,不用拆成好几个 Text。我们可以在 Text() 里放多个 Span

Text() {
  Span('同一行文字里,')
    .fontSize(15)
    .fontColor('#334155')
  Span('真正要强调的词')
    .fontSize(15)
    .fontWeight(700)
    .fontColor('#2563EB')
    .textBackgroundStyle({ color: '#DBEAFE', radius: 4 })
  Span(' 可以用 Span 单独处理,不用拆成好几个 Text。')
    .fontSize(15)
    .fontColor('#334155')
}
.width('100%')
.lineHeight(24)

这段代码的重点是:外层 Text() 管这一整行,里面每个 Span 管自己的样式。这样文字还在同一个排版上下文里,换行、行高、对齐都更自然。

小标签也适合用 Span。比如我们在句子前面放一个 NEW

Text() {
  Span('NEW')
    .fontSize(12)
    .fontWeight(700)
    .fontColor('#C2410C')
    .letterSpacing(1)
    .textCase(TextCase.UpperCase)
  Span(' 这种标签可以贴在句子开头,提示用户这是新内容。')
    .fontSize(15)
    .fontColor('#475569')
}
.width('100%')
.lineHeight(24)

这里我们故意没有把它做成按钮或徽章组件,因为它只是文字的一部分。用 Span 就够了,简单,也不容易把布局带偏。

ImageSpan 负责文字里的小图标

有些图标天然应该跟文字走,比如会员标识、状态标记、说明里的小图。这个时候用 ImageSpan 比额外写一个 Row 更轻。

Text() {
  ImageSpan($r('app.media.startIcon'))
    .width(18)
    .height(18)
    .verticalAlign(ImageSpanAlignment.CENTER)
    .objectFit(ImageFit.Contain)
  Span(' 会员标识可以跟文字在同一行,不用额外写 Row 去拼。')
    .fontSize(15)
    .fontColor('#334155')
}
.width('100%')
.lineHeight(26)

verticalAlign(ImageSpanAlignment.CENTER) 这句很关键。图片和文字默认不一定刚好在视觉中心,稍微一偏就会显得粗糙。

SVG 资源也可以放进 ImageSpan

Text() {
  Span('支持 ')
    .fontSize(15)
    .fontColor('#475569')
  ImageSpan($r('app.media.icon_huawei'))
    .width(18)
    .height(18)
    .verticalAlign(ImageSpanAlignment.CENTER)
    .objectFit(ImageFit.Contain)
  Span(' 这种小图标跟文字自然对齐,适合放在说明、标签或状态文案里。')
    .fontSize(15)
    .fontColor('#475569')
}
.width('100%')
.lineHeight(26)

这类图文混排不适合搞太复杂。图片只做辅助,尺寸别太大,文字才是主角。

长句别放任它乱长

列表摘要、商品描述、卡片标题,都可能遇到长文本。我们给它最多两行,超出就省略。

Text('这是一段故意写长的文字,用来展示 maxLines 和 textOverflow。真实业务里,卡片标题、列表摘要、商品描述都可能需要截断,否则一个长句就能把整个布局撑乱。')
  .width('100%')
  .fontSize(15)
  .fontColor('#334155')
  .lineHeight(24)
  .maxLines(2)
  .textOverflow({ overflow: TextOverflow.Ellipsis })

这块很实用。你只要做过列表,大概率都被长标题折磨过。

看效果时盯这几处

打开案例页面后,别只看“有没有显示”。我们重点看这几件事:

  • 正文和标题有没有拉开层级。
  • 主信息、次信息、警示信息有没有各站各的位置。
  • Span 的强调词是不是还在同一行文字节奏里。
  • ImageSpan 的小图标有没有和文字居中对齐。
  • 长段落读起来挤不挤。
  • 最后一段是不是最多两行,后面带省略号。

你在 DevEco Studio 里打开案例页面看就行,不用急着改业务代码,先观察文字层级有没有舒服一点。

顺手改两处

可以把 Span('真正要强调的词') 的背景色换成浅绿色,看看强调感会不会变弱。

也可以把 ImageSpan 的尺寸从 18 改成 1422。你会很直观地看到:图标只要大一点,就可能从“辅助信息”变成“抢戏信息”。

你平时写说明文案时,更常遇到哪种麻烦:一句话里几个字要强调,还是图标和文字总是对不齐?可以直接说说你的场景。

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/basic/ArkUITextDemo.ets

@Entry
@Component
struct ArkUITextDemo {
  @Builder
  sectionTitle(title: string) {
    Text(title)
      .width('100%')
      .fontSize(15)
      .fontWeight(700)
      .fontColor('#334155')
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI Text')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('文字不是能显示就够了')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('今天我们只做一件事:把文字层级调顺。先看字号、颜色、行高、Span、ImageSpan 和截断,别急着往页面里塞更多组件。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('基础文本')

          Text('普通正文适合用 14 到 16 的字号,颜色不要太黑。')
            .width('100%')
            .fontSize(15)
            .fontColor('#475569')
            .lineHeight(24)

          Text('标题文本要有层级')
            .width('100%')
            .fontSize(20)
            .fontWeight(700)
            .fontColor('#0F172A')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F8FAFC')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('颜色和强调')

          Text('主信息:用户第一眼应该看到这一句')
            .width('100%')
            .fontSize(16)
            .fontWeight(700)
            .fontColor('#1D4ED8')

          Text('次信息:补充说明放轻一点,别和主信息抢注意力')
            .width('100%')
            .fontSize(14)
            .fontColor('#64748B')

          Text('警示信息:颜色可以提醒风险,但不要把整页都染红')
            .width('100%')
            .fontSize(14)
            .fontWeight(600)
            .fontColor('#B91C1C')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E2E8F0' })
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('Span 局部强调')

          Text() {
            Span('同一行文字里,')
              .fontSize(15)
              .fontColor('#334155')
            Span('真正要强调的词')
              .fontSize(15)
              .fontWeight(700)
              .fontColor('#2563EB')
              .textBackgroundStyle({ color: '#DBEAFE', radius: 4 })
            Span(' 可以用 Span 单独处理,不用拆成好几个 Text。')
              .fontSize(15)
              .fontColor('#334155')
          }
          .width('100%')
          .lineHeight(24)

          Text() {
            Span('NEW')
              .fontSize(12)
              .fontWeight(700)
              .fontColor('#C2410C')
              .letterSpacing(1)
              .textCase(TextCase.UpperCase)
            Span(' 这种标签可以贴在句子开头,提示用户这是新内容。')
              .fontSize(15)
              .fontColor('#475569')
          }
          .width('100%')
          .lineHeight(24)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('ImageSpan 图文混排')

          Text() {
            ImageSpan($r('app.media.startIcon'))
              .width(18)
              .height(18)
              .verticalAlign(ImageSpanAlignment.CENTER)
              .objectFit(ImageFit.Contain)
            Span(' 会员标识可以跟文字在同一行,不用额外写 Row 去拼。')
              .fontSize(15)
              .fontColor('#334155')
          }
          .width('100%')
          .lineHeight(26)

          Text() {
            Span('支持 ')
              .fontSize(15)
              .fontColor('#475569')
            ImageSpan($r('app.media.icon_huawei'))
              .width(18)
              .height(18)
              .verticalAlign(ImageSpanAlignment.CENTER)
              .objectFit(ImageFit.Contain)
            Span(' 这种小图标跟文字自然对齐,适合放在说明、标签或状态文案里。')
              .fontSize(15)
              .fontColor('#475569')
          }
          .width('100%')
          .lineHeight(26)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F7FEE7')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('行高和对齐')

          Text('长文本不要只设置字号。行高太紧,读起来会挤;行高太松,页面会散。这个段落设置了 lineHeight,让多行文字更容易扫读。')
            .width('100%')
            .fontSize(15)
            .fontColor('#334155')
            .lineHeight(25)

          Text('居中适合短标题,不适合长正文')
            .width('100%')
            .fontSize(16)
            .fontWeight(700)
            .fontColor('#0F766E')
            .textAlign(TextAlign.Center)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F0FDFA')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('多行截断')

          Text('这是一段故意写长的文字,用来展示 maxLines 和 textOverflow。真实业务里,卡片标题、列表摘要、商品描述都可能需要截断,否则一个长句就能把整个布局撑乱。')
            .width('100%')
            .fontSize(15)
            .fontColor('#334155')
            .lineHeight(24)
            .maxLines(2)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFF7ED')
        .borderRadius(8)
      }
      .width('100%')
      .padding(20)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。