移动开发中的 Ellipsize — 什么是文本截断及方法

作者: IT Sectr 发布日期: 2026-07-25 阅读时间: 8 分钟

Ellipsize — 是一种文本截断机制,不是在像素级别裁剪行,而是在末尾或中间添加省略号符号 (…),向用户指示文本未完全显示在容器中。此技术用于标题、按钮、联系人列表以及任何宽度受限的 UI 组件。根据 Google Material Design 指南,ellipsize 是 TextView 和 UILabel 的标准行为,支持四种截断模式:开头、中间、结尾和滚动文本。

要点

  • Ellipsize — 在截断位置添加省略号来截断长文本。
  • Android 支持 4 种模式:START、MIDDLE、END、MARQUEE
  • iOS 使用 NSLineBreakMode,包含 .byTruncatingHead、.byTruncatingMiddle、.byTruncatingTail。
  • 在 Web 中,CSS 属性 text-overflow: ellipsis 配合 overflow: hidden 可实现相同效果。
  • 模式选择取决于数据类型:END — 用于标题,MIDDLE — 用于文件路径。

什么是 Ellipsize?

Ellipsize(来自英语 ellipsis — 省略号)— 是一种显示超出容器尺寸文本的技术。不是简单地在边界处裁剪行(clip),ellipsize 会添加省略号符号(Unicode U+2026),向用户指示存在隐藏内容。

这个术语在 Android SDK 中已经确立,其中 android:ellipsize 属性决定了 TextView 在溢出时的行为。在 iOS 上,类似的功能称为 truncation(截断),通过 NSLineBreakMode 进行管理。在 Web 上,使用 CSS 属性 text-overflow,值为 ellipsis。

Ellipsize 的主要目标是 告知用户文本已被缩短。与像素级裁剪不同(单词可能被切成两半),ellipsize 保证了可读性:省略号放在完整单词或字符之后,不会将其打断。这符合 Material Design 和 Human Interface Guidelines 的原则。

只要容器宽度固定且文本长度动态,就应使用 ellipsize:文章标题、表格单元格、带标签的按钮、列表中的联系人、面包屑导航和文件路径。

Android 中的 Ellipsize:TextView 和模式

在 Android 中,ellipsize 通过 XML 中的 android:ellipsize 属性或代码中的 setEllipsize() 方法进行配置。有四种可用模式,每种模式决定文本从哪一侧被截断。

END 模式(大多数情况下的默认值)截断行尾并将省略号放在容器右侧。START 模式截断开头 — 省略号在左侧,可见文本在右侧。MIDDLE 截断中间,保留行的开头和结尾可见。MARQUEE 模式 — 文本的动画滚动,不显示省略号,文本循环滚动。

xml
<!-- XML layout -->
<TextView
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="Very long text that will be truncated"
    android:ellipsize="end"
    android:maxLines="1"
    android:singleLine="true" />

<!-- Kotlin code -->
textView.setEllipsize(TextUtils.TruncateAt.MIDDLE)

重要:ellipsize 仅与 maxLines 或 singleLine 组合使用。如果不限制行数,TextView 将在高度上增长,ellipsize 不会激活。从 Android 8.0 (API 26) 开始,ellipsize 支持 maxLines > 1 的多行模式 — 省略号放在最后一行的末尾。

对于编程调用,使用 TextUtils.TruncateAt,值为:END、START、MIDDLE、MARQUEE。NONE 值禁用 ellipsize。

在实践中,END 适用于 90% 的情况 — 用户期望文本在末尾被截断。MIDDLE 用于文件路径(例如 "/User/.../project/main.kt"),以便路径末尾可见。START — 用于具有共同前缀的名称(例如 "...@gmail.com")。

iOS 中的文本截断:NSLineBreakMode

在 iOS 上,ellipsize 的等效项是 UILabel 类的 lineBreakMode 属性(以及 UITextView 的 NSTextContainer)。有三种截断模式可用:.byTruncatingTail(结尾)、.byTruncatingMiddle(中间)和 .byTruncatingHead(开头)。

.byTruncatingTail 模式对应于 android:ellipsize="end"。.byTruncatingHead 模式 — START,.byTruncatingMiddle — MIDDLE。.byClipping 模式 — 截断文本但不显示省略号,在现代界面中很少使用。.byCharWrapping 模式 — 按字符换行而不截断。

swift
let label = UILabel()
label.text = "超出标签边界的长文本"
label.lineBreakMode = .byTruncatingMiddle
label.numberOfLines = 1

// NSAttributedString 也支持 lineBreakMode
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingTail

在 iOS 中,截断与 numberOfLines 配合使用。如果 numberOfLines = 1,文本在一行上截断。如果 numberOfLines = 2 — 在第二行上。UITextView 使用 NSTextContainer.lineBreakMode,它也支持所有三种截断模式。

iOS 的特点:UILabel 上的 .byTruncatingMiddle 模式在短行上可能表现异常 — 如果行完全适合,省略号不会出现。为确保短行上显示省略号,请通过 sizeThatFits 使用自定义逻辑。

CSS text-overflow:如何在 Web 中创建省略号

在 Web 中,ellipsize 通过 CSS 属性 text-overflow: ellipsis 结合 overflow: hidden 和 white-space: nowrap 实现。这是在 Web 界面中使用省略号截断行的标准方法。

css
.text-cell {
    width: 250px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

text-overflow 属性在没 overflow: hidden 的情况下不起作用 — 浏览器需要知道内容被截断。white-space: nowrap 禁止换行,否则文本将转到下一行,不会发生溢出。

对于多行截断(例如,第二行末尾带省略号的 2 行),以前使用实验性属性 -webkit-line-clamp,现在已在 CSS Overflow Level 4 中标准化为 line-clamp

在实践中,text-overflow: ellipsis 已被所有现代浏览器支持超过 10 年,是 Web 中截断文本最可靠的方法。

如何选择正确的截断模式

选择 ellipsize 模式 会影响 UX,既能改善界面的感知,也可能使用户困惑。主要原则:用户期望截断部分位于最不需要理解的地方。

END 模式适用于标题、标签、名称 — 用户看到行的开头并理解上下文。右侧的省略号表示 “有继续,但没显示下”。这是最直观和最广泛使用的模式。

MIDDLE 模式对于文件路径、电子邮件地址和长标识符必不可少。当行尾包含唯一信息(文件名、域名)时,用户应该看到它,而开头可以缩短。例如:"/User/.../important_document.pdf" — 立即看到文件名。

START 模式很少使用,但对于具有共同前缀的联系人列表很有用 — 例如 "...@gmail.com" 代替 "username@gmail.com",当所有地址属于同一域名时。然而,这种模式更多是令人困惑而不是有帮助。根据 Nielsen Norman Group 的数据,用户从左到右阅读,期望重要信息在开头,因此 START 截断增加了认知负荷。

MARQUEE 模式(滚动文本)仅适用于低更新频率的单行元素:播放器中的当前曲目、新闻滚动条、状态栏。不要在表格、列表或表单中使用 marquee — 动画会分散注意力并降低弱设备的性能。

常见问题及解决方案

第一个问题 — ellipsize 不生效。最常见的原因是缺少行数限制。没有 maxLines,TextView 高度增长,不会发生宽度溢出。解决方案:始终指定 maxLines(或 singleLine="true" 用于单行)。

第二个问题 — 编程更改文本时省略号不显示。调用 setText() 后,TextView 可能无法正确重绘。解决方案:更改文本后调用 invalidate() 或 post(() -> requestLayout())。

第三个问题 — 不同 Android 版本上的不同行为。在 API 23 之前,ellipsize 在多行模式 (maxLines > 1) 中不受支持。解决方案:为兼容性检查 Build.VERSION.SDK_INT 并使用 AndroidX 中的 ViewCompat.setEllipsize()。

第四个问题 — 省略号符号在自定义字体中不显示。如果字体不包含 U+2026 字形,省略号将被替换为三个点。解决方案:检查字体是否包含省略号字形,或通过 fontFamily 添加后备字体。

常见问题解答

在 Android 中,ellipsize 必须指定 maxLines 吗?

是的,maxLines 或 singleLine 是必需的。不限制行数,TextView 将高度扩展,截断不会激活。

Ellipsize 和 clip 有什么区别?

Ellipsize 在中断位置添加省略号,告知用户存在隐藏文本。Clip 只是简单地在边界处截断文本,没有任何指示符。

如何在 CSS 中在单词中间创建省略号?

标准 text-overflow: ellipsis 在完整单词后截断。要在单词中间截断,请使用 overflow-wrap: break-word 或使用测量宽度的 JavaScript 解决方案。

Ellipsize 在 iOS 的 UITextView 中有效吗?

是的,通过 NSTextContainer 中的 textContainer.lineBreakMode 属性。默认情况下,UITextView 使用 .byWordWrapping;改为 .byTruncatingTail/Middle/Head 进行截断。

如何以编程方式禁用 TextView 中的省略号?

调用 textView.setEllipsize(null)textView.setEllipsize(TextUtils.TruncateAt.NONE)。之后文本将换行而不是截断。

总结

  • Ellipsize — 一种文本截断机制,通过添加省略号指示隐藏内容。
  • Android 通过 TextUtils.TruncateAt 支持 END、START、MIDDLE、MARQUEE 模式。
  • iOS 使用 NSLineBreakMode,包含 .byTruncatingTail、.byTruncatingMiddle 和 .byTruncatingHead。
  • 在 Web 中,省略号通过 text-overflow: ellipsis + overflow: hidden + nowrap 实现。
  • END 模式适用于大多数场景;MIDDLE — 用于文件路径和电子邮件。
  • 不限制行数(maxLines 或 numberOfLines),ellipsize 不工作。
  • 仅在特殊情况下使用 MARQUEE — 动画会分散注意力并降低 UX。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读