Created
October 23, 2024 17:05
-
-
Save dumazy/d5ee19ce3caa850bb1b4c5ed28a05139 to your computer and use it in GitHub Desktop.
Updating PopScope based on inner Navigator
This file contains 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
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: Builder( | |
builder: (context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Home')), | |
body: Center( | |
child: ElevatedButton( | |
onPressed: () => Navigator.of(context).push( | |
MaterialPageRoute( | |
builder: (_) => NestedNavScreen(), | |
), | |
), | |
child: Text('Open top level'), | |
), | |
), | |
); | |
}, | |
), | |
); | |
} | |
} | |
class NestedNavScreen extends StatefulWidget { | |
@override | |
State<NestedNavScreen> createState() => _NestedNavScreenState(); | |
} | |
class _NestedNavScreenState extends State<NestedNavScreen> { | |
final _navigatorKey = GlobalKey<NavigatorState>(); | |
Route _onGenerateRoute(RouteSettings settings) { | |
final routeName = settings.name!; | |
final routeIndex = int.parse(routeName); | |
return MaterialPageRoute( | |
builder: (_) => NestedPage(index: routeIndex), | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Nested Nav screen')), | |
body: PopScope( | |
// Don't pop if the inner nav can pop | |
// | |
// ------ | |
// We want PopScope to rebuild when the inner nav changes, so `canPop` has a new value. | |
// It might have the wrong value when the Android back button is used. | |
// ------ | |
canPop: _navigatorKey.currentState?.canPop() ?? true, | |
onPopInvokedWithResult: (didPop, _) { | |
// No need to pop the inner nav | |
if (didPop) return; | |
// Pop the inner nav | |
_navigatorKey.currentState?.pop(); | |
}, | |
child: Navigator( | |
key: _navigatorKey, | |
initialRoute: '1', | |
onGenerateRoute: _onGenerateRoute, | |
), | |
), | |
); | |
} | |
} | |
class NestedPage extends StatelessWidget { | |
NestedPage({required this.index}); | |
final int index; | |
@override | |
Widget build(BuildContext context) { | |
return Center( | |
child: Column( | |
children: [ | |
Text('Nested page: $index'), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
if (Navigator.of(context).canPop()) | |
ElevatedButton( | |
onPressed: () => Navigator.of(context).pop(), | |
child: Text('Go back'), | |
), | |
ElevatedButton( | |
onPressed: () => | |
Navigator.of(context).pushNamed('${index + 1}'), | |
child: Text('Open next'), | |
), | |
], | |
), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment