一张适合技术文章的手绘笔记风信息图,主题是 HarmonyOS 7 复杂首页的渲染层级性能排查。画面

前言

异常文案是检验布局韧性的最好材料。标题一长、按钮一多、屏幕一窄,平时看起来很整齐的卡片就可能把操作区挤没。

这篇单独聊 长标题卡片 这个场景。重点不是堆 API,而是用弹性布局保证极端文案、按钮和状态标签不会互相挤压。

为什么布局一碰到长文案就容易露馅

因为正常文案太容易把页面骗过去了。四五个字的标题、短短一行说明、两个字的按钮,看起来怎么排都顺。

可一旦换成真实业务里的异常标题、设备编号、英文长串和多语言翻译,很多原本“挺整齐”的布局马上就会露底:按钮被挤扁,标签换行,卡片高度失控。

所以这篇文章真正想解决的,不是让页面在理想文案下好看,而是让它在最麻烦的文案下也别崩。

场景:消息中心的异常通知卡片

真实业务里的文案不会总是四个字。订单异常、设备离线、地址识别失败、活动审核驳回,这些标题经常又长又具体。消息中心如果只按短文案设计,最常见的问题就是标题把按钮挤没,状态标签换行变形,或者整张卡片高度突然失控。

我做这类卡片时会先保护关键操作:按钮必须可点,状态必须可读,主文案可以伸缩和截断。也就是说,布局不是让所有内容都完整显示,而是在小屏和长文案下保住信息优先级。

UI 稳不稳,要看最长文案、最小屏幕、最大字号下会不会崩。

布局策略

元素布局策略原因
状态标签固定内容宽度,不参与伸缩避免“异常”被压变形
主标题layoutWeight(1) + maxLines吸收剩余空间
操作按钮固定宽高保证可点击区域
辅助说明单独放下一行避免和按钮抢空间
时间文案弱化显示信息重要性低于标题

实操步骤

  1. 先确定卡片里谁必须完整显示,通常是状态和按钮。
  2. 主标题放在可伸缩区域,使用 layoutWeight(1)
  3. 长文案设置 maxLinestextOverflow,不要撑破卡片。
  4. 辅助说明放到下一行,不要和操作按钮同排硬挤。
  5. 用短文案、长文案、无空格长串、较大字号都测一遍。
  6. 列表 key 使用业务 id,避免异常通知刷新时错位。

先把卡片里谁不能退让想清楚

做异常通知卡片时,先别急着调 RowColumn。更重要的是先判断:这一排里谁必须保住,谁可以让位。大多数情况下,操作按钮必须可点,状态标签必须可读,标题可以适当截断,辅助说明可以放到下一行。

你先把这个优先级排清楚,再去看 layoutWeight(1)、固定宽度和换行策略,就会明白这些 API 不是随便拼出来的,而是在帮你执行“谁保留、谁让位”这件事。对小白来说,这一步能明显减少布局一乱就只会反复试数值的情况。

完整示例:可承受长文案的通知列表

interface NoticeItem {
  id: number
  title: string
  desc: string
  action: string
  level: string
  time: string
}

@Entry
@Component
struct FlexibleTextPage {
  private notices: NoticeItem[] = [
    { id: 1, title: '订单已完成', desc: '可查看订单详情和发票信息。', action: '查看', level: 'normal', time: '09:20' },
    { id: 2, title: '由于收货地址包含无法识别的楼栋信息,当前配送任务需要用户重新确认详细地址', desc: '请在 24 小时内处理,否则配送任务会自动暂停。', action: '处理', level: 'warn', time: '10:48' },
    { id: 3, title: 'DEVICE-ALPHA-2026-SUPER-LONG-NAME-NEEDS-CHECK', desc: '设备名称来自外部系统,可能没有自然断句。', action: '检查', level: 'error', time: '11:03' }
  ]

  private levelText(level: string): string {
    if (level === 'error') {
      return '错误'
    }
    if (level === 'warn') {
      return '异常'
    }
    return '正常'
  }

  private levelColor(level: string): string {
    if (level === 'error') {
      return '#B42318'
    }
    if (level === 'warn') {
      return '#D92D20'
    }
    return '#0A7F3F'
  }

  @Builder
  NoticeCard(item: NoticeItem) {
    Column({ space: 8 }) {
      Row({ space: 10 }) {
        Text(this.levelText(item.level))
          .fontSize(12)
          .fontColor('#FFFFFF')
          .padding({ left: 6, right: 6, top: 3, bottom: 3 })
          .backgroundColor(this.levelColor(item.level))
          .borderRadius(4)

        Text(item.title)
          .fontSize(15)
          .fontColor('#222222')
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .layoutWeight(1)

        Button(item.action)
          .width(64)
          .height(32)
          .fontSize(12)
      }.width('100%')

      Row() {
        Text(item.desc)
          .fontSize(13)
          .fontColor('#666666')
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .layoutWeight(1)
        Text(item.time)
          .fontSize(12)
          .fontColor('#999999')
          .margin({ left: 8 })
      }.width('100%')
    }
    .alignItems(HorizontalAlign.Start)
    .padding(12)
    .backgroundColor('#FFFFFF')
    .borderRadius(8)
  }

  build() {
    Column({ space: 12 }) {
      Text('异常文案布局')
        .fontSize(22)
        .fontWeight(FontWeight.Bold)

      ForEach(this.notices, (item: NoticeItem) => {
        this.NoticeCard(item)
      }, (item: NoticeItem) => item.id.toString())
    }
    .padding(16)
    .backgroundColor('#F5F7FA')
    .height('100%')
  }
}

把关键代码一段段拆开

标题使用 layoutWeight(1),表示它占用标签和按钮之外的剩余空间。这样按钮不会被长标题挤出屏幕,标题也不会和操作区重叠。

maxLines(2) 比单行截断更适合异常通知。异常文案通常需要多一点上下文,两行能让用户看懂大概原因;超过两行再省略,避免卡片失控。

辅助说明放在第二行,和时间文案同排。主标题那一排已经有状态标签和按钮,不应该再塞更多信息。信息层级清楚了,弹性布局才有发挥空间。

容易踩坑的点

  • 标题不设置最大行数,长文案把卡片撑到半屏。
  • 按钮没有固定宽度,被标题挤到只剩几个像素。
  • 状态标签参与伸缩,文字被压缩或换行。
  • 只测试中文短句,没有测试英文长串、设备编号、异常码。
  • 辅助说明和按钮放在同一行,窄屏下互相抢空间。

优化建议

长文案不是单纯截断就完事。如果异常原因很重要,可以点击卡片进入详情页展示完整内容;列表里只保留摘要和动作。这样列表保持可扫读,详情页承接完整解释。

还要考虑字号放大和多语言。英文、数字、设备编号不一定有自然断点,布局压力比中文更大。做国际化或系统字号适配时,最好准备一组极端数据作为 UI 回归用例。

如果团队里经常有人因为改文案把布局改崩,我会把这些极端样例直接做成假数据常驻在开发环境里。这样每次改样式时都能顺手看到最坏情况,而不是等测试阶段才发现按钮已经被长标题挤没。

异常文案要按信息优先级让位

弹性布局不是让所有内容都完整显示,而是在空间不够时保住最重要的信息。异常通知里,状态标签和操作按钮通常必须可见,标题可以两行省略,辅助说明可以弱化或交给详情页承接。

示例让标题使用 layoutWeight(1) 吸收剩余空间,按钮保持固定宽高,状态标签不参与伸缩。这样长标题不会把按钮挤没,用户仍然能完成处理动作。

写在最后

测试时不要只放正常中文短句。英文长串、设备编号、异常码、系统字号放大、多语言翻译都会给布局制造压力。能扛住这些异常文案,卡片才算真正稳定。

Logo

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

更多推荐