Flutter间隔显示两个Dialog报错,请求技术排查解决
问题修复:先显示加载Dialog再切换到编辑号码Dialog
原代码核心问题
- 使用
Timer.periodic(重复定时器)而非单次定时器,会多次触发状态更新 showDialog返回Future而非Widget,不能直接作为页面body的子组件渲染- 在
build方法中直接调用异步方法,会导致组件每次重建都创建新定时器,引发异常 - 错误将对话框当作页面内组件处理,忽略了
showDialog是弹出浮层的特性
修复步骤
- 替换
Timer.periodic为单次Timer(或直接用Future.delayed),确保只执行一次切换逻辑 - 在
initState中初始化流程,避免build重复触发 - 正确管理对话框生命周期:先弹出加载Dialog,延迟后关闭它,再弹出编辑号码Dialog
- 移除错误的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
相关产品推荐
相关产品推荐

