Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active December 19, 2025 15:28
Show Gist options
  • Select an option

  • Save PlugFox/f8f63c1ab3a63e49085b356281887435 to your computer and use it in GitHub Desktop.

Select an option

Save PlugFox/f8f63c1ab3a63e49085b356281887435 to your computer and use it in GitHub Desktop.
Show dialogs from unmounted context
/*
* 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