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

Flutter间隔显示两个Dialog报错,请求技术排查解决

问题修复:先显示加载Dialog再切换到编辑号码Dialog

原代码核心问题

  • 使用Timer.periodic(重复定时器)而非单次定时器,会多次触发状态更新
  • showDialog返回Future而非Widget,不能直接作为页面body的子组件渲染
  • 在build方法中直接调用异步方法,会导致组件每次重建都创建新定时器,引发异常
  • 错误将对话框当作页面内组件处理,忽略了showDialog是弹出浮层的特性

修复步骤

  1. 替换Timer.periodic为单次Timer(或直接用Future.delayed),确保只执行一次切换逻辑
  2. 在initState中初始化流程,避免build重复触发
  3. 正确管理对话框生命周期:先弹出加载Dialog,延迟后关闭它,再弹出编辑号码Dialog
  4. 移除错误的Widget赋值逻辑,回归showDialog的浮层使用方式

完整修复代码

import 'dart:async';
import 'package:flutter/material.dart';

// 定义所需颜色常量(原代码中引用的green)
const Color green = Color(0xFF25D366);

class DialogWidgets extends StatefulWidget {
  const DialogWidgets({super.key});

  @override
  State<DialogWidgets> createState() => _DialogWidgetsState();
}

class _DialogWidgetsState extends State<DialogWidgets> {
  @override
  void initState() {
    super.initState();
    // 初始化时启动对话框切换流程
    _startDialogSequence();
  }

  Future<void> _startDialogSequence() async {
    // 弹出加载对话框,禁止外部点击关闭
    await showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return const Dialog(
          child: SizedBox(
            height: 85,
            width: 380,
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 20),
              child: Row(
                children: [
                  CircularProgressIndicator(color: green),
                  SizedBox(width: 20),
                  Text(
                    "Connecting...",
                    style: TextStyle(
                      fontSize: 16,
                      color: Colors.black45,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );

    // 弹出编辑号码对话框
    await showDialog(
      context: context,
      builder: (context) {
        return Dialog(
          child: Container(
            height: 220,
            width: 320,
            color: Colors.white,
            padding: const EdgeInsets.all(20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  "You entered the phone number",
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w400,
                  ),
                ),
                const SizedBox(height: 20),
                const Text(
                  "+91 88665 77577",
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 20),
                const Text(
                  "Is this OK, or would you like to edit the number?",
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w400,
                  ),
                ),
                const Spacer(),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    TextButton(
                      onPressed: () => Navigator.pop(context),
                      child: const Text(
                        "EDIT",
                        style: TextStyle(
                          color: green,
                          fontSize: 16,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                    ),
                    TextButton(
                      onPressed: () => Navigator.pop(context),
                      child: const Text(
                        "OK",
                        style: TextStyle(
                          color: green,
                          fontSize: 16,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text("主页面内容"), // 替换为你的实际主页面UI
      ),
    );
  }
}

关键说明

  • initState初始化:确保对话框切换流程只执行一次,避免重复触发
  • 对话框生命周期:通过Navigator.pop()在延迟后关闭加载Dialog,再打开新Dialog,避免浮层叠加
  • barrierDismissible: false:防止用户在加载过程中手动关闭Dialog,保证流程完整性
  • 回归showDialog本质:Dialog是独立于页面的浮层组件,不需要嵌入页面body中

内容的提问来源于stack exchange,提问作者Vishal D Rajpara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:45:05