前言
上一篇我们用Text组件把「猫猫大作战」主菜单的 Emoji + 主标题 + 副标题三行渲染完成。但实战中副标题往往不是一句话能写完的——可能是多行规则说明、可能是带省略号溢出的长描述、可能是多段不同样式的混排。本篇继续以「猫猫大作战」主菜单的规则说明面板为锚点,把Text的多行排版能力一口气讲透。
读完本篇你将能独立写出:自动换行的规则说明、溢出省略的长描述、居中对齐的多行文本,并为后续第 4 篇的 Column 卡片容器打好基础。
提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已用 DevEco Studio 6.1.1 Release 新建好工程并跟完第 1 篇。
一、场景拆解:规则说明面板到底要排版什么
打开entry/src/main/ets/pages/Index.ets的MainMenuView,找到「游戏规则」面板:
// 来源:entry/src/main/ets/pages/Index.ets MainMenuView() Column() { Text('游戏规则') .fontSize(14) .fontWeight(FontWeight.Bold) .fontColor('#2C3E50') .margin({ bottom: 8 }) Text('• 点击列投放猫咪') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 相邻同级猫咪自动合并升级') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 连续合并触发连击加分') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 猫咪堆到顶部则游戏结束') .fontSize(13) .fontColor('#7F8C8D') } .width('80%') .padding(16) .backgroundColor('rgba(255,255,255,0.7)') .borderRadius(12) .alignItems(HorizontalAlign.Start)这个面板由 5 段Text堆出来:1 个粗体小标题 + 4 条规则说明,每条规则以•引导。视觉上规则之间间距 4vp,标题与第一条规则间距 8vp,又是「近距分组」的排版思路。
但实战中规则说明可能会变长,比如改成一段连贯的话:「点击列投放猫咪,相邻同级猫咪自动合并升级,连续合并触发连击加分,猫咪堆到顶部则游戏结束」。这就需要Text的多行排版能力。
二、Text 多行排版核心属性速览
| 属性 | 类型 | 作用 | 默认值 |
|---|---|---|---|
maxLines | number | 最大行数,溢出部分按textOverflow处理 | 不限制 |
textOverflow | { overflow: TextOverflow } | 溢出样式:None/Clip/Ellipsis/MARQUEE | None |
textAlign | TextAlign 枚举 | 多行文本水平对齐 | Start |
lineHeight | string | number | 行高,影响多行间距 | 字号自动倍数 |
textCase | TextCase 枚举 | 大小写强制转换 | Normal |
wordBreak | WordBreak 枚举 | 换行规则,中文断词 | BREAK_WORD |
2.1 TextAlign 三值
TextAlign.Start // 左对齐(默认) TextAlign.Center // 居中 TextAlign.End // 右对齐主菜单整体用Column.alignItems(HorizontalAlign.Center)居中所有子元素,但规则面板用HorizontalAlign.Start左对齐——因为规则是阅读型内容,左对齐扫读效率最高。
2.2 TextOverflow 四值
TextOverflow.None // 不裁剪,超出就超出 TextOverflow.Clip // 直接裁掉超出部分 TextOverflow.Ellipsis // 显示省略号 … TextOverflow.MARQUEE // 跑马灯滚动(API 10+)实战最常用的是Ellipsis。MARQUEE适合广告横幅、通知栏,规则面板里用不上。
三、实战 1:自动换行的长说明
把规则改成一段连贯的话,让Text自动换行:
Text('点击列投放猫咪,相邻同级猫咪自动合并升级,连续合并触发连击加分,猫咪堆到顶部则游戏结束。') .fontSize(13) .fontColor('#7F8C8D') .lineHeight(20) // 行高 20vp,字号 13,行距舒展 .textAlign(TextAlign.Start) .width('100%') // 必须给宽度,否则换行不生效关键点:
- 必须给
width:Text默认宽度由内容撑开,不限制宽度就不会换行。给width('100%')让它撑满父容器,超出才会折行。 lineHeight比字号大:13 字号配 20 行高,行距舒展;不设lineHeight走默认约 1.2 倍字号,行间稍挤。textAlign只对多行有效:单行文本水平对齐由父容器决定。
提示:
lineHeight单位也是 vp。常见经验值是字号的 1.4–1.6 倍。13 字号 → 18–22 行高都合理。
四、实战 2:溢出省略的截断说明
如果说明更长,但面板空间有限,需要截断显示省略号:
Text('点击列投放猫咪,相邻同级猫咪自动合并升级,连续合并触发连击加分,猫咪堆到顶部则游戏结束,合并到传奇等级可获得额外奖励。') .fontSize(13) .fontColor('#7F8C8D') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) .lineHeight(20) .width('100%')关键点:
maxLines(2)+textOverflow.Ellipsis是一对黄金搭档,限制 2 行,超出显示…。- 不配
textOverflow只设maxLines:超出部分被裁掉但不显示省略号,用户不知道还有更多内容。 ClipvsEllipsis:Clip直接切,Ellipsis显示…句末,后者更友好。
效果示意:
| 配置 | 效果 |
|---|---|
maxLines(2)单独 | 2 行后硬切,无提示 |
maxLines(2)+Ellipsis | 2 行末尾…,提示有更多 |
不设maxLines | 全部显示,可能撑爆面板 |
五、实战 3:Span 混排多段不同样式
规则说明里想强调「同级」「连击」两个关键词,让它们变色加粗。这时单个Text办不到,需要Text套多个Span:
Text() { Span('• ') .fontColor('#7F8C8D') .fontSize(13) Span('相邻同级') .fontColor('#E74C3C') .fontSize(13) .fontWeight(FontWeight.Bold) Span('猫咪自动合并升级') .fontColor('#7F8C8D') .fontSize(13) } .width('100%') .lineHeight(20)Span 是行内文本组件,只能作为Text或RichEditor的子组件,单独使用不显示。它继承父Text的字号行高,也能局部覆盖样式。
提示:参考 文本显示 (Text/Span) 官方指南。Span 与 Text 同时配置内容时,Span 内容会覆盖 Text 内容——别在
Text('xxx')里再套Span,外层'xxx'会被丢弃。
六、实战 4:measureTextSize 测算行数
进阶场景:根据内容动态判断是否需要「展开/收起」按钮。HarmonyOS 提供measureTextSize测算文本尺寸:
import { } from '@kit.ArkUI' // 在组件方法内调用 const uiContext = this.getUIContext() const titleSize = uiContext.getMeasureUtils().measureTextSize({ textContent: this.fullRuleText, fontSize: 13, lineHeight: 20, constraintWidth: 280 // 限制宽度,与实际 Text 宽度一致 }) const heightVp = uiContext.px2vp(Number(titleSize.height)) const lineCount = Math.round(heightVp / 20) // 行高 20 → 算行数 if (lineCount > 2) { // 超过 2 行,显示展开按钮 this.needExpand = true }关键点:
constraintWidth要与实际Text的宽度一致,否则测出的行数不对。px2vp转换:measureTextSize返回的是 px,要转 vp。- API 20+新增
getParagraphs20+,更直观拿行数,参考 文本展开折叠官方指南。
七、完整代码:规则面板两种写法对比
7.1 原版:5 段 Text 分行(本项目当前写法)
Column() { Text('游戏规则') .fontSize(14) .fontWeight(FontWeight.Bold) .fontColor('#2C3E50') .margin({ bottom: 8 }) Text('• 点击列投放猫咪') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 相邻同级猫咪自动合并升级') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 连续合并触发连击加分') .fontSize(13) .fontColor('#7F8C8D') .margin({ bottom: 4 }) Text('• 猫咪堆到顶部则游戏结束') .fontSize(13) .fontColor('#7F8C8D') } .width('80%') .padding(16) .backgroundColor('rgba(255,255,255,0.7)') .borderRadius(12) .alignItems(HorizontalAlign.Start)7.2 进阶版:Span 混排 + 关键词高亮
Column() { Text('游戏规则') .fontSize(14) .fontWeight(FontWeight.Bold) .fontColor('#2C3E50') .margin({ bottom: 8 }) Text() { Span('• 点击列投放猫咪').fontSize(13).fontColor('#7F8C8D') } .lineHeight(20) .margin({ bottom: 4 }) Text() { Span('• 相邻').fontSize(13).fontColor('#7F8C8D') Span('同级').fontSize(13).fontColor('#E74C3C').fontWeight(FontWeight.Bold) Span('猫咪自动合并升级').fontSize(13).fontColor('#7F8C8D') } .lineHeight(20) .margin({ bottom: 4 }) Text() { Span('• 连续合并触发').fontSize(13).fontColor('#7F8C8D') Span('连击').fontSize(13).fontColor('#F39C12').fontWeight(FontWeight.Bold) Span('加分').fontSize(13).fontColor('#7F8C8D') } .lineHeight(20) .margin({ bottom: 4 }) Text() { Span('• 猫咪堆到顶部则').fontSize(13).fontColor('#7F8C8D') Span('游戏结束').fontSize(13).fontColor('#E74C3C').fontWeight(FontWeight.Bold) } .lineHeight(20) } .width('80%') .padding(16) .backgroundColor('rgba(255,255,255,0.7)') .borderRadius(12) .alignItems(HorizontalAlign.Start)进阶版让「同级」「连击」「游戏结束」三个关键词彩色加粗,视觉引导用户关注核心机制。
八、调试技巧:多行文本怎么对齐量
- 加临时 border:
.border({ width: 1, color: Color.Red })看清Text占框,调完去掉。 lineHeight调整:行间太挤就加lineHeight,太松就减。width验证:换行不生效多半是没给width,或给了'auto'。- 预览器 vs 真机:Emoji 和某些字体在预览器可能缺失,以真机为准。
九、性能与最佳实践
Span别嵌套太深:单Text内 5–8 个Span性能尚可,超过考虑拆多个Text。- 长文本用
maxLines+Ellipsis:避免长描述撑爆容器。 lineHeight统一:同一面板内所有Text的lineHeight取值一致,视觉才整齐。textAlign用对:阅读型内容Start,标题型Center,数字型End。
总结
本篇我们从规则说明面板切入,掌握Text的maxLines、textOverflow、textAlign、lineHeight四大多行排版属性,并用Span混排做了关键词高亮进阶。核心要点:width是换行前提,maxLines+Ellipsis是截断标配,Span是行内样式唯一解。
下一篇我们将继续主菜单,拆解「开始游戏」按钮的Button组件圆角与阴影效果。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 「猫猫大作战」项目源码:本仓库
entry/src/main/ets/pages/Index.ets - 文本显示 (Text/Span) 官方指南
- 文本展开折叠 — HarmonyOS 官方文档
- 文本概述 — HarmonyOS 官方文档
- Span 组件 API 参考
- 开源鸿蒙跨平台社区
- HarmonyOS 开发者官方文档首页
- 系列索引:本仓库
articles/INDEX.md