Last active
December 19, 2025 15:28
-
-
Save PlugFox/f8f63c1ab3a63e49085b356281887435 to your computer and use it in GitHub Desktop.
Show dialogs from unmounted context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Show dialogs from unmounted context | |
| * https://gist.github.com/PlugFox/f8f63c1ab3a63e49085b356281887435 | |
| * https://dartpad.dev?id=f8f63c1ab3a63e49085b356281887435 | |
| * Mike Matiunin <[email protected]>, 19 December 2025 | |
| */ | |
| import 'dart:async'; | |
| import 'package:flutter/material.dart'; | |
| void main() => runZonedGuarded<void>( | |
| () => runApp(const App()), | |
| (error, stackTrace) => print('Top level exception'), // ignore: avoid_print | |
| ); | |
| /// {@template app} | |
| /// App widget. | |
| /// {@endtemplate} | |
| class App extends StatelessWidget { | |
| /// {@macro app} | |
| const App({super.key}); | |
| @override | |
| Widget build(BuildContext context) => MaterialApp( | |
| title: 'Material App', | |
| home: Scaffold( | |
| appBar: AppBar(title: const Text('Material App Bar')), | |
| body: SafeArea( | |
| child: Center( | |
| child: Builder( | |
| builder: (context) => ElevatedButton( | |
| child: const Text('Hello World'), | |
| onPressed: () { | |
| showDoubleDialogs(context); | |
| }, | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| void showDoubleDialogs(BuildContext context) { | |
| // Get the navigator from the context | |
| // And use it to show the dialog even in unmounted situations | |
| final navigator = Navigator.maybeOf(context, rootNavigator: true); | |
| if (navigator == null) return; | |
| showDialog<void>( | |
| context: navigator.context, | |
| builder: (context) => AlertDialog( | |
| title: const Text('Dialog #1'), | |
| content: const Text( | |
| 'First dialog\n' | |
| 'Press button to pop it and show\n' | |
| ' another dialog after some delay.', | |
| ), | |
| actions: <Widget>[ | |
| TextButton( | |
| onPressed: () { | |
| if (!navigator.mounted) return; | |
| navigator.maybePop(); | |
| Timer(const Duration(seconds: 2), () { | |
| // We should not use just `context` here. | |
| // Because it could be unmounted | |
| if (!navigator.mounted) return; | |
| showDialog<void>( | |
| context: navigator.context, | |
| builder: (context) => AlertDialog( | |
| title: const Text('Dialog #2'), | |
| content: const Text( | |
| 'Second dialog\n' | |
| 'You can close it now.', | |
| ), | |
| actions: <Widget>[ | |
| TextButton( | |
| onPressed: () { | |
| if (!navigator.mounted) return; | |
| navigator.maybePop(); | |
| }, | |
| child: const Text('Pop it'), | |
| ), | |
| ], | |
| ), | |
| ); | |
| }); | |
| }, | |
| child: const Text('Pop it'), | |
| ), | |
| ], | |
| ), | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment