简体   繁体   中英

Flutter Nested Navigator back Issue on Web

The app has a nested navigator as below

import 'package:aa/routes.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.teal,
      ),
      initialRoute: root,
      onGenerateRoute: AppRouter.mainRouteSettings,
      navigatorKey: RouteConfig().appRouteKey,
    );
  }
}

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        RouteConfig().main.currentState!.maybePop();
        return false;
      },
      child: Scaffold(
        body: Container(
          margin: const EdgeInsets.all(100),
          decoration: BoxDecoration(
              color: Colors.grey[500], borderRadius: BorderRadius.circular(20)),
          child: Navigator(
            key: RouteConfig().main,
            initialRoute: one,
            onGenerateRoute: AppRouter.generateRoute,
          ),
        ),
      ),
    );
  }
}


import 'package:aa/main.dart';
import 'package:flutter/material.dart';

//Pre
const String root = '/';
const String preRoute = '/preRoute';

const String one = '/';
const String two = '/two';
const String three = '/three';

class RouteConfig {
  static final RouteConfig _routeConfig = RouteConfig._internal();
  factory RouteConfig() {
    return _routeConfig;
  }
  RouteConfig._internal();

  ///App Navigator Key
  GlobalKey<NavigatorState> appRouteKey = GlobalKey<NavigatorState>();

  ///Pre Auth Key
  GlobalKey<NavigatorState> main = GlobalKey<NavigatorState>();
}

class AppRouter {
  static Route mainRouteSettings(RouteSettings settings) {
    late Widget page;

    switch (settings.name) {
      case root:
        page = Scaffold(
          body: Container(
              child: TextButton(
                  onPressed: () => RouteConfig()
                      .appRouteKey
                      .currentState!
                      .pushReplacementNamed(preRoute),
                  child: Center(child: Text('Click Me')))),
        );
        break;
      case preRoute:
        page = Test();
        break;
      default:
        page = const Center(child: Text('Not Found'));
    }

    return MaterialPageRoute<dynamic>(
      builder: (context) {
        return page;
      },
      settings: settings,
    );
  }

  static Route generateRoute(RouteSettings settings) {
    late Widget page;

    print(settings.name);

    switch (settings.name) {
      case one:
        page = Builder(builder: (context) {
          return WillPopScope(
            onWillPop: () async => !Navigator.of(context).userGestureInProgress,
            child: Container(
              color: Colors.pink,
              margin: const EdgeInsets.all(3),
              child: Center(
                child: Column(
                  children: [
                    TextButton(
                      onPressed: () {
                        RouteConfig().main.currentState!.pop();
                      },
                      child: Text('pop'),
                    ),
                    TextButton(
                      onPressed: () {
                        RouteConfig().main.currentState!.pushNamed(two);
                      },
                      child: Text('dcdf'),
                    ),
                  ],
                ),
              ),
            ),
          );
        });
        break;
      case two:
        page = const Text('Two');
        break;
      case three:
        page = const Text('Three');
        break;
      default:
        page = const Center(child: Text('Not Found'));
    }

    return MaterialPageRoute<dynamic>(
      builder: (context) {
        return page;
      },
      settings: settings,
    );
  }
}

I am able to swipe back in the nested navigator. for example, after I tap on the pop button it pops the initial route of the nested navigator how can the Nestednavigator go back when it's the initial route of the app how to prevent this behavior.

Refer the Video for example

The workaround was

  • Programmatically we can navigate back it's a bug currently in flutter
  • to prevent browser back and hardware back add a willpopscope with return false to prevent back or swipe for back in ios

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM