如何在CupertinoAlertDialog中提示用户输入的邮箱无效?
规范简洁的Cupertino邮箱验证Dialog实现方案
下面是优化后的完整代码,结合Cupertino设计规范和Flutter最佳实践,解决你的输入反馈问题:
// 抽离邮箱验证方法,方便复用和维护 bool isValidEmail(String email) { // 标准邮箱正则,覆盖绝大多数合法格式 final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); return emailRegex.hasMatch(email); } Future showEmailAlertBox( Service serv, DateTime date, Duration dur, var price) async { bool showError = false; // 控制错误提示的显示状态 await showDialog( context: context, barrierDismissible: true, builder: (context) { // 用StatefulBuilder管理dialog内部状态,避免外部setState无法更新dialog UI return StatefulBuilder( builder: (context, setState) { return CupertinoAlertDialog( title: const Text('Enter Email Address to confirm'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ CupertinoTextField( controller: emailController, placeholder: 'your@email.com', keyboardType: TextInputType.emailAddress, // 优化输入键盘类型 decoration: BoxDecoration( border: Border.all( // 错误时显示Cupertino风格警示红边框 color: showError ? CupertinoColors.destructiveRed : CupertinoColors.systemGrey4, width: 1, ), borderRadius: BorderRadius.circular(8), ), onChanged: (_) { // 用户输入时自动隐藏错误提示 if (showError) { setState(() => showError = false); } }, ), // 仅在验证失败时显示错误文本 if (showError) Padding( padding: const EdgeInsets.only(top: 8), child: Text( 'Please enter a valid email address', style: TextStyle( color: CupertinoColors.destructiveRed, fontSize: 12, ), ), ), ], ), actions: <CupertinoDialogAction>[ CupertinoDialogAction( isDefaultAction: true, onPressed: () async { if (isValidEmail(emailController.text)) { // 执行预订创建逻辑 await dbhandler.createBooking( pickeddate, selectedTimeSlot, selectedDurationOption!.duration, selectedService!.title, price, ); await getAllBookings(); // 更新状态前判断widget是否挂载,避免空状态错误 if (!mounted) return; setState(() { availableTimeSlots = getTimeSlots( selectedDurationOption!.duration, pickeddate!, selectedService!, ); selectedTimeSlot = ''; }); _showConfettiAnimation(); Navigator.pop(context); emailController.clear(); // 清空输入框,避免残留内容 } else { // 触发错误提示状态更新 setState(() => showError = true); // 添加触觉反馈,贴合iOS交互习惯(需导入flutter/services.dart) HapticFeedback.mediumImpact(); } }, child: const Text('Confirm'), ), CupertinoDialogAction( isDestructiveAction: true, onPressed: () { decision = false; emailController.clear(); Navigator.pop(context); }, child: const Text('Cancel'), ), ], ); }, ); }, ); }
核心优化说明
- 严谨的邮箱验证:替换原有的简单
@检查逻辑,用正则覆盖更多无效场景(比如无域名后缀、@在首尾等)。 - 直观的错误反馈:验证失败时输入框显示红色边框,下方展示明确的错误文本;用户开始输入时自动隐藏错误,提升交互流畅度。
- 正确的状态管理:使用
StatefulBuilder处理dialog内部状态,解决外部setState无法更新dialog UI的问题。 - 内存与状态清理:操作完成后清空输入框,避免残留旧内容;更新状态前判断
mounted,防止widget销毁后触发错误。 - 细节优化:添加邮箱专用输入键盘,引导用户输入;触发错误时加入触觉反馈,贴合iOS平台交互习惯。
额外建议
如果不想自己维护正则表达式,可以使用email_validator第三方包,但自定义正则已经能覆盖绝大多数场景,可避免不必要的依赖。
内容的提问来源于stack exchange,提问作者Milan Labus
相关产品推荐
相关产品推荐

