You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:50:11