刷新数据传递后,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...已修复
依赖关系使用 [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...已修复