dependencies using [get: ^4.3.4,uni_links: ^0.5.1]
main.dart build method :
@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(),
);
}
I have using routerDelegate and routeInformationParser for navigation...
Home screen onPress code :
onPressed: () {
return routerDelegate.pushPage(
name: '/college',
arguments: {
"screenCode" : 7,
}
);
},
below code how I have receiving param data from navigated file :
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 file :
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 file :
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;
}
}
After navigation my url will be http://localhost:56127/#/college?id=7
my issue is after refresh that screen param data have changed to null like below
http://localhost:56127/#/college?id=null
Please revert how to resolve?
CodePudding user response:
Use Hive or secure storage to save your params locally. It won't get lost after refresh. Just read the saved params when you need it.
CodePudding user response:
Issue fixed :
I have done small mistake
onPressed: () {
return routerDelegate.pushPage(
name: '/college',
arguments: {
"screenCode" : 7,
}
);
},
if(routeSettings.name == '/college') {
return '?id=${(routeSettings.arguments as Map)['screenCode'].toString()}';
}
in onPressed function I declare key name as screenCode. but in routeSettings query Param I have declared as id.....so changed id to screenCode... fixed