一张适合技术文章的手绘笔记风信息图,主题是 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、测试、元服务和应用上架分发等。

更多推荐