在 Flutter 中,长标题、用户名或说明文字放进 Row 后,常会挤压图标、撑破布局,或显示不完整。下面通过一个名为 Overflower 的轻量自定义组件,统一处理文本行数、尾部省略和样式,再将它放入有明确宽度约束的布局中。这里的 Overflower 是本文示例定义的组件,不依赖额外插件。
先理解文本为什么会溢出
Text 需要根据父组件提供的宽度决定在哪里换行。若它处于 Row 内,而同一行还有头像、按钮等子组件,文本又没有获得有限的可用宽度,就可能出现黄色黑色条纹的溢出提示。仅给 Text 设置 overflow: TextOverflow.ellipsis 并不总能解决问题:父级仍需提供可计算的宽度。
因此处理时要分两步:先用 Expanded、Flexible 或明确宽度约束安排空间,再让文本组件按行数截断。Overflower 将第二步封装起来,让相同规则可以在列表、卡片和标题区域重复使用。
封装 Overflower 组件
新建 overflower.dart,加入以下代码。组件接收文本、最大行数、文字样式和对齐方式,默认只显示一行,超出部分以省略号收尾。
import 'package:flutter/material.dart';
class Overflower extends StatelessWidget {
const Overflower({
super.key,
required this.text,
this.maxLines = 1,
this.style,
this.textAlign = TextAlign.start,
}) : assert(maxLines > 0);
final String text;
final int maxLines;
final TextStyle? style;
final TextAlign textAlign;
@override
Widget build(BuildContext context) {
return Text(
text,
maxLines: maxLines,
overflow: TextOverflow.ellipsis,
style: style,
textAlign: textAlign,
);
}
}
maxLines 控制最多展示几行,TextOverflow.ellipsis 指定超出后的呈现方式。将 style 设为可选参数,调用方就能按所在页面设置字号、颜色和字重;textAlign 则负责控制文本对齐。构造函数中的断言用于避免传入零或负数行数。
放进 Row:给文本分配剩余宽度
下面是一个常见的资料行布局:左侧显示头像,中间展示昵称和简介,右侧保留操作按钮。中间内容放进 Expanded,可以取得头像与按钮之外的剩余宽度,避免文本挤出屏幕。
Row(
children: [
const CircleAvatar(
radius: 22,
child: Icon(Icons.person),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Overflower(
text: '春日城市漫步与沿途咖啡店记录',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 4),
Overflower(
text: '沿街散步,整理本周拍摄的照片和路线',
maxLines: 2,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_vert),
),
],
)
标题使用默认的单行设置,较长时收成一行省略号;简介设置 maxLines: 2,最多占两行,再多的文字同样会被截断。示例中的 Expanded 是关键:删除它后,Row 内的文本可能无法得到合适的宽度约束。
在其他布局中控制宽度
如果 Overflower 单独放在卡片或对话框中,可以由外层容器限定最大宽度:
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 320),
child: const Overflower(
text: '较长的卡片标题会在可用宽度内自动省略',
),
)
在列表项中,若标题区域已经由 ListTile 管理,通常可直接放入 title 或 subtitle。遇到嵌套布局时,重点检查文本一路向上的父级是否提供了有限宽度,而不是反复调整字号来掩盖约束问题。
常见问题与调整方式
- 省略号没有出现:检查文本是否获得有限宽度,并确认设置了
maxLines和TextOverflow.ellipsis。在横向滚动等无界宽度区域,应先给文本容器设置宽度或最大宽度。 - 按钮被挤出屏幕:不要让文本与按钮都无约束地占用空间。将文本区域放入
Expanded,让按钮保留自身所需宽度。 - 简介需要多行:调用时传入大于一的
maxLines,并给外层布局足够的垂直空间。行数代表显示上限,不会强制短文字补足空行。 - 不同页面需要不同外观:通过
style传入对应的TextStyle,而不是把颜色、字号固定在组件内部。这样同一组件可用于标题、备注和列表摘要。
完成封装后,页面只需传入文本和显示规则即可复用省略逻辑。记住,Overflower 负责文本截断,外层组件负责提供合理约束;两者配合,才能稳定处理 Flutter 中的长文本布局。
