Flutter无按钮关闭AlertDialog及登录加载错误处理问题
Got it, let's break down your problem and fix this step by step. You want to show a progress indicator dialog when the login button is tapped, automatically close that dialog if an error (like wrong email/password) occurs, then display an error dialog—no manual button needed to close the progress dialog.
Your current approach with IndexedStack isn't working because the dialog's builder only runs once; updating isError won't trigger a UI rebuild for the dialog. Instead, we can handle this by separating the progress and error dialogs, and using Flutter's navigation system to programmatically close the progress dialog when an error hits.
Here's the revised implementation:
First, update your login button's onPressed handler to manage the dialogs explicitly:
onPressed: () async { // Show the progress dialog first showDialog( barrierDismissible: false, context: context, builder: (BuildContext dialogContext) { return const AlertDialog( content: Row( children: [ CircularProgressIndicator(), SizedBox(width: 16), Text("Loading..."), ], ), ); }, ); try { // Attempt login final user = await _auth.signInWithEmailAndPassword( email: email, password: pass, ); // Login success: close the progress dialog and handle navigation/logic Navigator.of(context).pop(); // Add your post-login logic here (e.g., navigate to home screen) } catch (err) { // Error occurred: first close the progress dialog Navigator.of(context).pop(); // Then show the error dialog with your matched message await showDialog( context: context, builder: (BuildContext dialogContext) { return AlertDialog( title: const Text("Error Found"), content: Text(finderror(err.code)), // Your error message lookup function actions: [ TextButton( child: const Text("Try Again"), onPressed: () { Navigator.of(dialogContext).pop(); }, ), ], ); }, ); } }
Key improvements explained:
- Separate dialogs: We no longer try to toggle content in a single dialog. Instead, we show a dedicated progress dialog, then replace it with an error dialog when needed.
- Programmatic closure:
Navigator.of(context).pop()in thecatchblock immediately closes the progress dialog—no button required. This works because the progress dialog is the topmost route in the navigation stack. - Context safety: Using the dialog's own context (from the builder) for closing the error dialog ensures we don't accidentally close the wrong route. If you ever run into context issues, add
rootNavigator: trueto theNavigator.ofcall (e.g.,Navigator.of(context, rootNavigator: true).pop()).
Why your original IndexedStack approach failed:
The showDialog builder function runs only once when the dialog is created. Changing the isError variable later doesn't trigger a rebuild of the dialog, since it's not part of a stateful widget that's listening to changes. Separating the dialogs avoids this state management headache entirely.
内容的提问来源于stack exchange,提问作者Faslur Rajah

