Flutter中TextOverflow.ellipsis能否忽略末尾空格再添加省略号?
解决Flutter TextOverflow.ellipsis末尾空格问题的思路
系统默认的TextOverflow.ellipsis会在省略号前留空格,想要让省略号和最后一个有效字符紧贴,可通过以下几种方式实现:
自定义文本截断逻辑
借助TextPainter计算文本在指定宽度下的可显示长度,手动截断后去除末尾空格,再拼接省略号:String truncateText(String text, TextStyle style, double maxWidth) { final textPainter = TextPainter( text: TextSpan(text: text, style: style), maxLines: 1, textDirection: TextDirection.ltr, )..layout(maxWidth: maxWidth); if (!textPainter.didExceedMaxLines) return text; // 逐步缩短文本直到符合宽度限制 String truncated = text; while (true) { truncated = truncated.substring(0, truncated.length - 1); textPainter.text = TextSpan(text: truncated, style: style); textPainter.layout(maxWidth: maxWidth); if (!textPainter.didExceedMaxLines) break; } // 移除末尾空格后拼接省略号 truncated = truncated.trimRight(); return '$truncated...'; } // 使用示例 Text( truncateText( 'This is an example of a string that needs an ellipses', TextStyle(fontSize: 14), 200, ), )自定义绘制文本(基于CustomPainter)
完全自定义文本绘制流程,先处理好截断后的文本(去空格),再将文本和省略号分别绘制,确保两者紧贴:class CustomEllipsisText extends StatelessWidget { final String text; final TextStyle style; final double maxWidth; const CustomEllipsisText({ super.key, required this.text, required this.style, required this.maxWidth, }); @override Widget build(BuildContext context) { return CustomPaint( painter: _EllipsisTextPainter( text: text, style: style, maxWidth: maxWidth, ), ); } } class _EllipsisTextPainter extends CustomPainter { final String text; final TextStyle style; final double maxWidth; _EllipsisTextPainter({ required this.text, required this.style, required this.maxWidth, }); @override void paint(Canvas canvas, Size size) { final textPainter = TextPainter( text: TextSpan(text: text, style: style), maxLines: 1, textDirection: TextDirection.ltr, )..layout(maxWidth: maxWidth); // 文本未超长直接绘制 if (!textPainter.didExceedMaxLines) { textPainter.paint(canvas, Offset.zero); return; } // 截断文本并预留省略号宽度 String truncated = text; while (true) { truncated = truncated.substring(0, truncated.length - 1); textPainter.text = TextSpan(text: truncated, style: style); textPainter.layout(maxWidth: maxWidth - (style.fontSize ?? 14)); if (!textPainter.didExceedMaxLines) break; } // 移除末尾空格 truncated = truncated.trimRight(); // 绘制主体文本 final mainTextPainter = TextPainter( text: TextSpan(text: truncated, style: style), textDirection: TextDirection.ltr, )..layout(); mainTextPainter.paint(canvas, Offset.zero); // 紧贴主体文本绘制省略号 final ellipsisPainter = TextPainter( text: TextSpan(text: '...', style: style), textDirection: TextDirection.ltr, )..layout(); ellipsisPainter.paint(canvas, Offset(mainTextPainter.width, 0)); } @override bool shouldRepaint(covariant _EllipsisTextPainter oldDelegate) { return text != oldDelegate.text || style != oldDelegate.style || maxWidth != oldDelegate.maxWidth; } } // 使用示例 CustomEllipsisText( text: 'This is an example of a string that needs an ellipses', style: TextStyle(fontSize: 14), maxWidth: 200, )用RichText组合文本与省略号
先处理好截断去空格的文本,再通过RichText将文本和省略号拼接成一个整体,避免系统默认的空格:Widget buildEllipsisText(String text, TextStyle style, double maxWidth) { final textPainter = TextPainter( text: TextSpan(text: text, style: style), maxLines: 1, textDirection: TextDirection.ltr, )..layout(maxWidth: maxWidth); if (!textPainter.didExceedMaxLines) { return Text(text, style: style); } String truncated = text; while (true) { truncated = truncated.substring(0, truncated.length - 1); textPainter.text = TextSpan(text: truncated, style: style); textPainter.layout(maxWidth: maxWidth - (style.fontSize ?? 14)); if (!textPainter.didExceedMaxLines) break; } truncated = truncated.trimRight(); return RichText( text: TextSpan( children: [ TextSpan(text: truncated, style: style), TextSpan(text: '...', style: style), ], ), maxLines: 1, overflow: TextOverflow.visible, ); } // 使用示例 buildEllipsisText( 'This is an example of a string that needs an ellipses', TextStyle(fontSize: 14), 200, ),
内容的提问来源于stack exchange,提问作者androidneil
相关产品推荐
相关产品推荐

