Skip to content

Instantly share code, notes, and snippets.

@schultek
Last active March 26, 2024 15:24
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save schultek/cc2acd8014be255c2a639a98d47be4e0 to your computer and use it in GitHub Desktop.
Save schultek/cc2acd8014be255c2a639a98d47be4e0 to your computer and use it in GitHub Desktop.
An improved WillPopScope widget to allow for nested navigators. See https://github.com/flutter/flutter/issues/47088
import 'package:flutter/material.dart';
class NestedWillPopScope extends StatefulWidget {
const NestedWillPopScope({
Key? key,
required this.child,
required this.onWillPop,
}) : super(key: key);
final Widget child;
final WillPopCallback onWillPop;
@override
_NestedWillPopScopeState createState() => _NestedWillPopScopeState();
static _NestedWillPopScopeState? of(BuildContext context) {
return context.findAncestorStateOfType<_NestedWillPopScopeState>();
}
}
class _NestedWillPopScopeState extends State<NestedWillPopScope> {
ModalRoute<dynamic>? _route;
_NestedWillPopScopeState? _descendant;
_NestedWillPopScopeState? get descendant => _descendant;
set descendant(_NestedWillPopScopeState? state) {
_descendant = state;
updateRouteCallback();
}
Future<bool> onWillPop() async {
bool? willPop;
if (_descendant != null) {
willPop = await _descendant!.onWillPop();
}
if (willPop == null || willPop) {
willPop = await widget.onWillPop();
}
return willPop;
}
void updateRouteCallback() {
_route?.removeScopedWillPopCallback(onWillPop);
_route = ModalRoute.of(context);
_route?.addScopedWillPopCallback(onWillPop);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
var parentGuard = NestedWillPopScope.of(context);
if (parentGuard != null) {
parentGuard.descendant = this;
}
updateRouteCallback();
}
@override
void dispose() {
_route?.removeScopedWillPopCallback(onWillPop);
super.dispose();
}
@override
Widget build(BuildContext context) => widget.child;
}
@yashhema
Copy link

Hello,
How to use the key functionality, say for example I have tabs and I want to keep track of them

@mt-akar
Copy link

mt-akar commented Jan 23, 2022

Is there a null-safe version for this?

@schultek
Copy link
Author

@m-azyoksul Here you go.

@bonkerman
Copy link

bonkerman commented Oct 18, 2022

Thanks a lot for this. However this is not complete and can cause errors. You should set the descendant of the parent to null on disposing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment