// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This sample demonstrates showing a confirmation dialog before navigating // away from a page. import 'package:flutter/material.dart'; void main() => runApp(const PageApiExampleApp()); class PageApiExampleApp extends StatefulWidget { const PageApiExampleApp({super.key}); @override State createState() => _PageApiExampleAppState(); } class _PageApiExampleAppState extends State { final RouterDelegate delegate = MyRouterDelegate(); @override Widget build(BuildContext context) { return MaterialApp.router(routerDelegate: delegate); } } class MyRouterDelegate extends RouterDelegate with PopNavigatorRouterDelegateMixin, ChangeNotifier { // This example doesn't use RouteInformationProvider. @override Future setNewRoutePath(Object configuration) async => throw UnimplementedError(); @override final GlobalKey navigatorKey = GlobalKey(); static MyRouterDelegate of(BuildContext context) => Router.of(context).routerDelegate as MyRouterDelegate; bool get showDetailPage => _showDetailPage; bool _showDetailPage = false; set showDetailPage(bool value) { if (_showDetailPage == value) { return; } _showDetailPage = value; notifyListeners(); } Future _showConfirmDialog() async { return await showDialog( context: navigatorKey.currentContext!, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: const Text('Are you sure?'), actions: [ TextButton( child: const Text('Cancel'), onPressed: () { Navigator.of(context).pop(false); }, ), TextButton( child: const Text('Confirm'), onPressed: () { Navigator.of(context).pop(true); }, ), ], ); }, ) ?? false; } Future _handlePopDetails(bool didPop, void result) async { if (didPop) { showDetailPage = false; return; } final bool confirmed = await _showConfirmDialog(); if (confirmed) { showDetailPage = false; } } List> _getPages() { return >[ const MaterialPage(key: ValueKey('home'), child: _HomePage()), if (showDetailPage) MaterialPage( key: const ValueKey('details'), child: const _DetailsPage(), canPop: false, onPopInvoked: _handlePopDetails, ), ]; } @override Widget build(BuildContext context) { return Navigator( key: navigatorKey, pages: _getPages(), onDidRemovePage: (Page page) { assert(page.key == const ValueKey('details')); showDetailPage = false; }, ); } } class _HomePage extends StatefulWidget { const _HomePage(); @override State<_HomePage> createState() => _HomePageState(); } class _HomePageState extends State<_HomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Home')), body: Center( child: TextButton( onPressed: () { MyRouterDelegate.of(context).showDetailPage = true; }, child: const Text('Go to details'), ), ), ); } } class _DetailsPage extends StatefulWidget { const _DetailsPage(); @override State<_DetailsPage> createState() => _DetailsPageState(); } class _DetailsPageState extends State<_DetailsPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Details')), body: Center( child: TextButton( onPressed: () { Navigator.of(context).maybePop(); }, child: const Text('Go back'), ), ), ); } }