如何在TextFormField中对超长文本进行截断,实现类似Text的overflow.ellipse效果?
TextFormField 超长文本溢出省略号实现方案
TextFormField 未内置和Text组件一致的overflow参数,可根据使用场景选择以下两种实现方式:
1. 只读展示场景(无需编辑)
直接通过InputDecoration的hintText承载展示内容,配置hint的样式即可实现省略号效果:
TextFormField( enabled: false, maxLines: 1, decoration: InputDecoration( hintText: "需要展示的超长文本内容", hintStyle: const TextStyle( overflow: TextOverflow.ellipsis, color: Colors.black, // 调整为正常文本的显示颜色 fontSize: 14 ), border: InputBorder.none, // 根据需求调整边框样式 contentPadding: EdgeInsets.zero // 根据需求调整内边距 ), )
2. 可编辑场景(支持用户输入)
自定义TextEditingController,重写buildTextSpan方法实现文本溢出自动截断加省略号:
class EllipsisTextController extends TextEditingController { @override TextSpan buildTextSpan({ required BuildContext context, TextStyle? style, required bool withComposing }) { final parentSpan = super.buildTextSpan( context: context, style: style, withComposing: withComposing ); // 调整maxWidth为输入框实际可显示的宽度,按需修改 final maxWidth = MediaQuery.of(context).size.width - 32; final textPainter = TextPainter( text: parentSpan, maxLines: 1, textDirection: TextDirection.ltr )..layout(maxWidth: maxWidth); // 文本未超出直接返回 if (!textPainter.didExceedMaxLines) return parentSpan; // 二分法查找合适的截断位置 int left = 0, right = text.length; while (left < right) { final mid = (left + right + 1) ~/ 2; final testSpan = TextSpan( text: '${text.substring(0, mid)}...', style: style ); textPainter.text = testSpan; textPainter.layout(maxWidth: maxWidth); if (textPainter.didExceedMaxLines) { right = mid - 1; } else { left = mid; } } return TextSpan( text: '${text.substring(0, left)}...', style: style ); } }
使用时将自定义控制器传入TextFormField,同时配置maxLines: 1即可:
TextFormField( controller: EllipsisTextController(), maxLines: 1, // 其他配置项 )
效果参考
内容的提问来源于stack exchange,提问作者Afdal
相关产品推荐
相关产品推荐

