如何使用 GoRouter 和 StatefulShell 检测 Flutter 中的路由退出是否是由浏览器后退按钮或 context.go 触发的?

问题描述 投票:0回答:1

我正在开发一个 Flutter Web 项目,使用 GoRouter 和 StatefulShell 进行路由管理。我想区分由浏览器后退按钮触发的路线退出和使用

context.go
的编程导航。

在我的

onExit
路线方法中,我需要以不同的方式处理这两种情况。

如何检测路由退出是由用户点击浏览器的后退按钮引起的,还是由我的代码使用

context.go()
触发的?

这是我如何使用

GoRouter
StatefulShell
的示例:

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

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

// private navigators
final _rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorMainPageKey =
    GlobalKey<NavigatorState>(debugLabel: 'main');
final _shellNavigatorSettingsPageKey =
    GlobalKey<NavigatorState>(debugLabel: 'settings');

final GoRouter _router = GoRouter(
  navigatorKey: _rootNavigatorKey,
  routes: [
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) {
        // the UI shell
        return HomePage(navigationShell: navigationShell);
      },
      branches: [
        StatefulShellBranch(
          navigatorKey: _shellNavigatorMainPageKey,
          routes: [
            GoRoute(
              path: '/',
              onExit: (context, state) {
                log(
                  'here check if we pressed browser back button or changing the page from the navigator rails',
                );
                return true;
              },
              pageBuilder: (context, state) => const NoTransitionPage(
                child: MainPage(),
              ),
            ),
          ],
        ),
        // second branch (B)
        StatefulShellBranch(
          navigatorKey: _shellNavigatorSettingsPageKey,
          routes: [
            GoRoute(
              path: '/settings',
              onExit: (context, state) {
                log(
                  'here check if we pressed browser back button or changing the page from the navigator rails',
                );
                return true;
              },
              pageBuilder: (context, state) => const NoTransitionPage(
                child: SettingsPage(),
              ),
            ),
          ],
        ),
      ],
    ),
  ],
);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
      title: 'My App',
      theme: ThemeData(
        useMaterial3: true,
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  final StatefulNavigationShell navigationShell;

  const HomePage({
    super.key,
    required this.navigationShell,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          NavigationRail(
            selectedIndex: _selectedIndex,
            onDestinationSelected: (int index) {
              setState(() {
                _selectedIndex = index;
              });
              if (index == 0) {
                context.go('/');
              } else if (index == 1) {
                context.go('/settings');
              }
            },
            labelType: NavigationRailLabelType.selected,
            destinations: const <NavigationRailDestination>[
              NavigationRailDestination(
                icon: Icon(
                  Icons.home,
                ),
                label: Text('Main'),
              ),
              NavigationRailDestination(
                icon: Icon(
                  Icons.settings,
                ),
                label: Text('Settings'),
              ),
            ],
          ),
          const VerticalDivider(thickness: 1, width: 2),
          Expanded(
            child: widget.navigationShell,
          )
        ],
      ),
    );
  }
}

class MainPage extends StatelessWidget {
  const MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'main page',
        ),
      ),
    );
  }
}

class SettingsPage extends StatelessWidget {
  const SettingsPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Setting page',
        ),
      ),
    );
  }
}


flutter navigation back-button flutter-go-router
1个回答
0
投票

您可以使用监听器 _router.routerDelegate.addListener(_onRouteChanged);

并在流中检测它 刷新监听:GoRouterRefreshStream( Stream.fromFuture(Future.microtask(() => null)), ),

© www.soinside.com 2019 - 2024. All rights reserved.