如何在Flutter的extended_text_field库中集成WidgetSpan?求示例
在ExtendedTextField中集成WidgetSpan(以EmailText为例)
1. 添加依赖
先确保pubspec.yaml中引入extended_text_field:
dependencies: flutter: sdk: flutter extended_text_field: ^latest_version # 替换为当前最新版本
2. 定义EmailText组件
实现自定义的邮箱样式组件(可根据需求调整交互和样式):
class EmailText extends StatelessWidget { final String email; final VoidCallback? onTap; const EmailText({super.key, required this.email, this.onTap}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Text( email, style: const TextStyle( color: Colors.blue, decoration: TextDecoration.underline, ), ), ); } }
3. 自定义SpecialTextSpanBuilder
这是核心逻辑,负责识别文本中的邮箱并替换为WidgetSpan包裹的EmailText:
class EmailSpecialTextSpanBuilder extends SpecialTextSpanBuilder { // 正则匹配邮箱格式 static final RegExp _emailRegex = RegExp( r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'); @override SpecialText? createSpecialText(String flag, {TextStyle? textStyle, SpecialTextGestureTapCallback? onTap, int? index}) { return null; } @override InlineSpan build(String data, {TextStyle? textStyle, onTap}) { final spans = <InlineSpan>[]; int currentIndex = 0; // 全局扫描文本中的邮箱 Iterable<Match> matches = _emailRegex.allMatches(data); for (Match match in matches) { // 添加邮箱之前的普通文本 if (match.start > currentIndex) { spans.add(TextSpan( text: data.substring(currentIndex, match.start), style: textStyle, )); } // 添加邮箱对应的WidgetSpan spans.add(WidgetSpan( child: EmailText( email: match.group(0)!, onTap: () { debugPrint('点击邮箱:${match.group(0)}'); // 可扩展逻辑:比如唤起邮箱应用、复制邮箱等 }, ), )); currentIndex = match.end; } // 添加剩余的普通文本 if (currentIndex < data.length) { spans.add(TextSpan( text: data.substring(currentIndex), style: textStyle, )); } return TextSpan(children: spans); } }
4. 在ExtendedTextField中集成
将自定义的Builder配置到输入框中:
class EmailTextFieldPage extends StatefulWidget { const EmailTextFieldPage({super.key}); @override State<EmailTextFieldPage> createState() => _EmailTextFieldPageState(); } class _EmailTextFieldPageState extends State<EmailTextFieldPage> { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('带邮箱组件的输入框')), body: Padding( padding: const EdgeInsets.all(16.0), child: ExtendedTextField( controller: _controller, specialTextSpanBuilder: EmailSpecialTextSpanBuilder(), decoration: const InputDecoration( hintText: '输入包含邮箱的内容', border: OutlineInputBorder(), ), maxLines: null, ), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } } // 启动示例 void main() { runApp(const MaterialApp(home: EmailTextFieldPage())); }
关键说明
- 自定义
SpecialTextSpanBuilder会实时解析输入文本,将匹配到的邮箱自动替换为EmailText组件 - 若需要调整邮箱匹配规则,直接修改正则表达式即可
- WidgetSpan支持包裹任意Widget,可根据需求扩展EmailText的样式(比如添加头像、标记)或交互逻辑
内容的提问来源于stack exchange,提问作者user3808307
相关产品推荐
相关产品推荐

