I am trying to achieve a common outcome that feels like it should be very straightforward: When the user hits the back button the navigation drawer opens, and if they press the back button again, while the drawer is still open, the app closes.
Unfortunately PopScope is not behaving in the way that I would expect it to, and I’m not sure if I’m doing something wrong, or if maybe PopScope has a bug.
//...
class PopScopeAintWorking extends StatelessWidget {
PopScopeAintWorking ({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Container(color: Colors.red),
),
body: Builder(builder: (context) {
return PopScope(
canPop: Scaffold.of(context).isDrawerOpen,
onPopInvoked: ((didPop) {
print("canPop: ${Scaffold.of(context).isDrawerOpen.toString()}");
print("didPop: ${didPop.toString()}");
if (!didPop) {
print("Did not pop.");
Scaffold.of(context).openDrawer();
} else {
print("Pop.");
}
}),
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: PageController(),
children: [Container(color: Colors.blue)],
),
);
}),
);
}
}
When the user is viewing PageView.page[0] and taps the Android ‘back’ button twice…
Expected result:
The first time the back button is tapped, canPop: Scaffold.of(context).isDrawerOpen
should be ‘false’, so therefore ‘didPop’ should be ‘false’, the app should not pop, and instead the drawer should open.
The second time the back button is tapped, canPop: Scaffold.of(context).isDrawerOpen
should be ‘true’, so therefore ‘didPop’ should be ‘true’, and the app should pop.
Actual result:
The first time the back button is tapped, canPop: Scaffold.of(context).isDrawerOpen
is ‘false’, so therefore ‘didPop’ is also ‘false’, the app does not pop, and the drawer opens instead.
The second time the back button is tapped, canPop: Scaffold.of(context).isDrawerOpen
is ‘true’, but for some reason ‘didPop’ is ‘false’, and the app does not pop.
Console output:
After first tap of the back button:
canPop: false
didPop: false
Did not pop.
After second tap of the back button:
canPop: true
didPop: false
Did not pop.