Open tolotrasamuel opened 4 years ago
I think the root issue here is in the way the current navigator works. You can't push or pop anything below the current active route.
Have you tried using the new navigator 2.0 pages api? I wonder if it's possible to do it in that, where the navigation stack is more malleable.
@tolotrasamuel explained very accurately. Did anyone found any solution till now?
I'd like to see this feature too
I have the same experience as you. In the end, I chose Overlay
to achieve this. The side effect is that this dialog is always at the top level.
The same problem exists in the case of showModalBottomSheet
.
In our app, many sheets can be presented on top of each other and we need to have the ability to control which ones get popped.
Navigator.pop() is not a sufficient API for Dialogs and Sheets.
Many waiting months later... :/
You can play around this
final route = DialogRoute(
context: context,
builder: (_)=>MyDialogView(),
barrierDismissible: false
);
Navigator.of(context).push(route);
// close dialog
Navigator.of(context).removeRoute(route);
You can play around this
final route = DialogRoute( context: context, builder: (_)=>MyDialogView(), barrierDismissible: false ); Navigator.of(context).push(route); // close dialog Navigator.of(context).removeRoute(route);
Or dive into
Important to note the following from Navigator.removeRoute
:
The removed route is disposed without being notified. The future that had been returned from pushing that routes will not complete.
You'll probably have to play around with completers and the like to get this to work as expected.
I have a case where a info dialog comes up after a delay. if the user has a dialog open and calls pop, the pop will be used on the info dialog and not the dialog I want to close. Any work arounds that work correctly in all cases?
Using pop
to close a dialog doesn't make much sense. You need to find out if the dialog is currently on screen. It could have already been dismissed, and popping would be like hitting the back button.
any updated?
any updated?
Extended showDialog:
Future<T?> showDialogAdvance<T>({
required WidgetBuilder builder,
bool barrierDismissible = true,
bool closePreviousDialog = false,
}) {
final appServ = AppService.instance;
final context = appServ.overlayCtx();
assert(debugCheckHasMaterialLocalizations(context));
final CapturedThemes themes = InheritedTheme.capture(
from: context,
to: Navigator.of(
context,
rootNavigator: true,
).context,
);
if (closePreviousDialog) {
appServ.closeCurrentDialog();
}
final route = DialogRoute<T>(
context: context,
builder: builder,
barrierColor: Colors.black54,
barrierDismissible: barrierDismissible,
barrierLabel: null,
useSafeArea: true,
settings: null,
themes: themes,
anchorPoint: null,
traversalEdgeBehavior: TraversalEdgeBehavior.closedLoop,
);
final future = Navigator.of(context, rootNavigator: true).push<T>(route);
appServ.setCurrentDialogRoute(route);
future.whenComplete(() => appServ.setCurrentDialogRoute(null));
return future;
}
Navigation Service:
class AppService {
static final instance = AppService._();
AppService._();
RootStackRouter? _appRouter;
RootStackRouter? get appRouter => _appRouter;
void setRouter(RootStackRouter appRouter) {
_appRouter ??= appRouter;
}
BuildContext overlayCtx() => _appRouter!.navigatorKey.currentContext!;
/// Dialog
DialogRoute? _dialogRoute;
void closeCurrentDialog() {
if (_dialogRoute != null) {
Navigator.of(overlayCtx(), rootNavigator: true)
.removeRoute(_dialogRoute!);
_dialogRoute = null;
}
}
void setCurrentDialogRoute(DialogRoute? dialogRoute) =>
_dialogRoute = dialogRoute;
}
In my case, I needed to open the bottom sheet while closing the dialog, but the sheet was closed instead.
I have the same experience as you. In the end, I chose
Overlay
to achieve this. The side effect is that this dialog is always at the top level.
too,i'm hate the getx and flutter
Please check this issue.
This issue is missing a priority label. Please set a priority label when adding the triaged-design
label.
2024 👍
这个问题竟然经历了 4 年。
Any solution now?
Use case
Currently, there is no way to close a specific alert dialog.
In Flutter, the only way to close a specific dialog is by this dialoge itself like this
Now what if the parent widget wants to close this dialog? The problem with
Navigator.of(context).pop()
is that it will close the topmost widget on the Navigation stack, not this specific dialog.Consider the following reproducible example to illustrate this issue:
Steps to reproduce:
Copy paste the below code in DartPad.dev/flutter
Hit run
Click the
Do Api Call
buttonyou should see two popups, one below and one above
After 5 seconds, the one below is desired to close not the one above, instead, the one above closes
How to close the one below and leave the one above open ?
Proposal
In Android, you just do:
dialog.dismiss();
In Flutter, there should be a way to get the reference to each specific dialog Please make this as a
P0
feature request because it is a very basic feature that Android does it so easily and it used so frequently by developers.