Flutter:显示AlertDialog后无需点击按钮自动调用函数的方法
实现AlertDialog显示后自动调用TTS朗读内容
需求描述
开发文本转语音功能,希望弹出AlertDialog后自动调用speak函数朗读弹窗内容,目前仅能通过点击按钮触发,相关代码如下:
朗读函数代码
speak(String text) async { await flutterTts.setLanguage('en-US'); await flutterTts.setPitch(1); await flutterTts.speak(text); }
AlertDialog代码片段
child: AlertDialog( contentPadding: EdgeInsets.zero, clipBehavior: Clip.antiAlias, content: Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: RichText( text: TextSpan( text: '${view.description}\n'
解决方案
方法一:封装带状态的弹窗组件
将AlertDialog封装为StatefulWidget,利用initState生命周期在弹窗初始化完成后自动触发朗读:
class AutoSpeakAlertDialog extends StatefulWidget { final String contentText; const AutoSpeakAlertDialog({ super.key, required this.contentText, }); @override State<AutoSpeakAlertDialog> createState() => _AutoSpeakAlertDialogState(); } class _AutoSpeakAlertDialogState extends State<AutoSpeakAlertDialog> { @override void initState() { super.initState(); _triggerSpeak(); } Future<void> _triggerSpeak() async { await flutterTts.setLanguage('en-US'); await flutterTts.setPitch(1); await flutterTts.speak(widget.contentText); } @override Widget build(BuildContext context) { return AlertDialog( contentPadding: EdgeInsets.zero, clipBehavior: Clip.antiAlias, content: Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: RichText( text: TextSpan( text: '${widget.contentText}\n', // 补充你的其他TextSpan内容 ), ), ), ), ], ), ); } }
调用方式:
showDialog( context: context, builder: (context) => AutoSpeakAlertDialog(contentText: view.description), );
方法二:使用PostFrameCallback即时触发
无需封装新组件,在弹窗内容中通过Builder和WidgetsBinding的回调确保弹窗绘制完成后执行朗读:
showDialog( context: context, builder: (context) => AlertDialog( contentPadding: EdgeInsets.zero, clipBehavior: Clip.antiAlias, content: Builder( builder: (context) { WidgetsBinding.instance.addPostFrameCallback((_) { speak(view.description); }); return Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: RichText( text: TextSpan( text: '${view.description}\n', // 补充你的其他TextSpan内容 ), ), ), ), ], ); }, ), ), );
注意事项
- 确保
flutterTts实例已完成初始化,避免调用时出现异常 - 若弹窗内容为异步加载,需配合
FutureBuilder等组件等待内容就绪后再触发朗读
内容的提问来源于stack exchange,提问作者ASMA
相关产品推荐
相关产品推荐

