刷新数据传递后,Flutter deepLinking 从初始屏幕(主屏幕)导航到下一个屏幕(大学屏幕)变为空

Flutter deepLinking navigate from initial screen(home screen) to next screen(college screen) after refreshing data passed become null

依赖关系使用 [get: ^4.3.4,uni_links: ^0.5.1]

main.dart 构建方法:

@override   
Widget build(BuildContext context) {
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      title: 'Navigator 2.0 Deep Link',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerDelegate: routerDelegate,
      routeInformationParser: const MyRouteInformationParser(),
    );   
}

我已经使用 routerDelegate 和 routeInformationParser 进行导航...

主屏幕按下代码:

          onPressed: () {
          return routerDelegate.pushPage(
            name: '/college',
            arguments: {
              "screenCode" : 7,
            }
          );
        },

下面是我如何从导航文件接收参数数据的代码:

class College extends StatefulWidget {
   final Map<String,dynamic> arguments;
   const College({Key? key,required this.arguments}) : super(key: key);

  @override
  _CollegeState createState() => _CollegeState();
}

information_parser.dart 文件:

import 'package:flutter/material.dart';

class MyRouteInformationParser
    extends RouteInformationParser<List<RouteSettings>> {
  const MyRouteInformationParser() : super();

  @override
  Future<List<RouteSettings>> parseRouteInformation(
      RouteInformation routeInformation) {
    final uri = Uri.parse(routeInformation.location!);

    if (uri.pathSegments.isEmpty) {
      return Future.value([const RouteSettings(name: '/')]);
    }

    final routeSettings = uri.pathSegments
        .map((pathSegment) => RouteSettings(
              name: '/$pathSegment',
              arguments: pathSegment == uri.pathSegments.last
                  ? uri.queryParameters
                  : null,
            ))
        .toList();

    return Future.value(routeSettings);
  }

  @override
  RouteInformation restoreRouteInformation(List<RouteSettings> configuration) {
    final location = configuration.last.name;
    final arguments = _restoreArguments(configuration.last);

    return RouteInformation(location: '$location$arguments');
  }

  String _restoreArguments(RouteSettings routeSettings) {
    if(routeSettings.name == '/college') {
      return '?id=${(routeSettings.arguments as Map)['screenCode'].toString()}';
    } else {
      return '';
    }
  }
}

delegate.dart 文件:

import 'package:flutter/material.dart';
import 'package:nav_bar/ui/college.dart';
import 'package:nav_bar/ui/hostel.dart';
import 'package:nav_bar/ui/stadium.dart';
import '../router/transition_delegate.dart';
import '../ui/home.dart';

class MyRouterDelegate extends RouterDelegate<List<RouteSettings>>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<List<RouteSettings>> {
  final _pages = <Page>[];

  @override
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  List<Page> get currentConfiguration => List.of(_pages);

  @override
  Widget build(BuildContext context) {
    return Navigator(
        key: navigatorKey,
        pages: List.of(_pages),
        onPopPage: _onPopPage,
        transitionDelegate: const MyTransitionDelegate());
  }

  @override
  Future<bool> popRoute() {
    if (_pages.length > 1) {
      _pages.removeLast();
      notifyListeners();
      return Future.value(true);
    }

    return _confirmAppExit();
  }

  @override
  Future<void> setNewRoutePath(List<RouteSettings> configuration) {
    _setPath(configuration
        .map((routeSettings) => _createPage(routeSettings))
        .toList());
    return Future.value(null);
  }

  void parseRoute(Uri uri) {
    if (uri.pathSegments.isEmpty) {
      setNewRoutePath([const RouteSettings(name: '/')]);
    } else {
      setNewRoutePath(uri.pathSegments
          .map((pathSegment) => RouteSettings(
                name: '/$pathSegment',
                arguments: pathSegment == uri.pathSegments.last
                    ? uri.queryParameters
                    : null,
              ))
          .toList());
    }
  }

  bool _onPopPage(Route route, dynamic result) {
    if (!route.didPop(result)) return false;

    popRoute();
    return true;
  }

  void _setPath(List<Page> pages) {
    _pages.clear();
    _pages.addAll(pages);

    if (_pages.first.name != '/') {
      _pages.insert(0, _createPage(const RouteSettings(name: '/')));
    }
    notifyListeners();
  }

  void pushPage({required String name, dynamic arguments}) {
    _pages.add(_createPage(RouteSettings(name: name, arguments: arguments)));
    notifyListeners();
  }

  MaterialPage _createPage(RouteSettings routeSettings) {
    Widget child;

    switch (routeSettings.name) {
      case '/':
        child = const HomePage();
        break;
      case '/college':
        child = College(arguments: routeSettings.arguments as Map<String,dynamic>);
        break;
      case '/hostel':
        child = Hostel();
        break;
      case '/stadium':
        child = Stadium();
        break;
      default:
        child = Scaffold(
          appBar: AppBar(title: const Text('404')),
          body: const Center(child: Text('Page not found')),
        );
    }

    return MaterialPage(
      child: child,
      key: Key(routeSettings.toString()) as LocalKey,
      name: routeSettings.name,
      arguments: routeSettings.arguments,
    );
  }

  Future<bool> _confirmAppExit() async {
    final result = await showDialog<bool>(
        context: navigatorKey!.currentContext!,
        builder: (context) {
          return AlertDialog(
            title: const Text('Exit App'),
            content: const Text('Are you sure you want to exit the app?'),
            actions: [
              TextButton(
                child: const Text('Cancel'),
                onPressed: () => Navigator.pop(context, true),
              ),
              TextButton(
                child: const Text('Confirm'),
                onPressed: () => Navigator.pop(context, false),
              ),
            ],
          );
        });

    return result ?? true;
  }
}

导航后我的 url 将是 http://localhost:56127/#/college?id=7

我的问题是刷新后屏幕参数数据已更改为 null,如下所示

http://localhost:56127/#/college?id=null

请回复如何解决?

使用Hive or secure storage 在本地保存您的参数。刷新后不会丢失。只需在需要时读取保存的参数即可。

问题已解决:

我犯了一个小错误

onPressed: () {
          return routerDelegate.pushPage(
            name: '/college',
            arguments: {
              "screenCode" : 7,
            }
          );
        },
if(routeSettings.name == '/college') {
      return '?id=${(routeSettings.arguments as Map)['screenCode'].toString()}';
    }

在 onPressed 函数中,我将键名声明为 screenCode。但在 routeSettings 查询参数中,我已声明为 id.....所以将 id 更改为 screenCode...已修复