navigation_saver 0.3.3
navigation_saver: ^0.3.3 copied to clipboard
This library will help to restore navigation stack after application kill.
Flutter navigation saver library (core module) #
This library will help to restore navigation stack after application kill.
Overview #
This is the core library and usually shouldn't be used directly. Please check general readme first. It should be used directly only if you would like have a full control of how routes are saved and restored.
How to use this library: #
- Be sure that you need exactly this core library. It has just base logic and all other big things like saving and restoring routes and arguments you will have to do by yourself.
Please check built value module (githib link or pub link) or json module (github link or pub link) for argument to map converting logic.
Please check shared prefreferences module (github link or pub link) for disk saving logic.
- If you still want to use this core library directly - include dependency:
navigation_saver: ^0.3.3- current module - Create
NavigationSaverclass before your application widget:
import 'package:build_value_navigation_saver/navigation_saver_routes_info.dart';
import 'package:shared_pref_navigation_saver/shared_pref_navigation_saver.dart';
void main() {
final NavigationSaver _navigatorSaver = NavigationSaver(
(routes) async => /* todo: add save code */,
() async => /* todo: add restore code */,
);
runApp(MyApp(_navigatorSaver));
}
- Setup
NavigationSaveras navigation observer and route generator:
class MyApp extends StatelessWidget {
MyApp(this._navigationSaver);
final NavigationSaver _navigationSaver;
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: NavigationSaver.restoreRouteName,
onGenerateRoute: (RouteSettings routeSettings) => _navigationSaver.onGenerateRoute(
routeSettings,
(
RouteSettings settings,
String routeName,
Object routeArguments, {
NextPageInfo nextPageInfo,
}) => /* todo: generate your application widgets here. use `routeName` and `routeArguments` */,
),
navigatorObservers: [_navigationSaver],
);
}
}
- This is it. Also you may want to add custom restoration widget that will be shown when library restore your navigation stack. This can be done by passing
restoreRouteWidgetBuilderparameter inonGenerateRoutemethod. - You may want to add custom restoration widget that will be shown when library restore your navigation stack. This can be done by passing
restoreRouteWidgetBuilderparameter inonGenerateRoutemethod.
How does core module work: #
-
Saves application navigation stack to the class field by implementing NavigatorObserver
-
Fires save routes callback when user stays on this route for some time.
-
defaultNavigationRouteparameter is used when there is no routes to restore and this route will be pushed in that case. Default value isNavigator.defaultRouteName. -
restorePreviousRoutesmethod that will clear all current navigation stack and replace it with the restored state. This method should be called only in the application launch. -
onGenerateRoutemethod that will check passed route settings and decide the way how it should be handled. Currently we have only 2 ways:a. If the name of the route is
NavigationSaver.restoreRouteName- library will push custom widget that will callrestorePreviousRoutes. You may want to customize how does it look like by passingrestoreRouteWidgetBuilderparameter.b. In all other cases library will check it the route arguments are from the restoration pushing or not.
ba. If this route was pushed by the client code (not the restoration), then it will call
NavigationSaverRouteFactorywith passed settings, routeName = settings.name and routeArguments = settings.arguments. Also nextPageInfo will be null.bb. If this route was pushed by the restoration logic, then it will call
NavigationSaverRouteFactorywith passed settings, routeName = settings.name and routeArguments = restoredRouteArguments (note that after the restoration settings.arguments will haveRestoredArgumentstype (See RestoredArguments). Also nextPageInfo will NOT be null if there is any next route above this one. This may be usefull if you need a result of the next route. See [how should I get a result of the next route after the kill].
RestoredArguments #
Flutter has a great feature in the navigation - you can wait for the next page result by using await keyword. And because when we restore the navigation stack we want to keep this ability we restore all routes with the new argument (RestoredArguments) class. This class has 2 fields: real page arguments and the next page information (NextPageInfo). See what can you do with it bellow.
How should I get a result of the next route after the kill (NextPageInfo class) #
Imagine you had a stack of widgets A -> B. And widget A was waiting for result of B. Usually you do this by using such code:
final result = await Navigator.of(context).pushNamed(
"/next",
arguments: SomeArgs(),
);
// do some work with the result
After the restoration logic the widget stack will be the same: A -> B. But there will be a big difference: widget A has never started the widget B - we did this in our library. But if you still want to get the result from B, you will need to use NextPageInfo class.
One of the best usage if this class:
- Save
nextPageInfofield in your widget class:
class AWidget extends StatefulWidget {
AWidget({
Key key,
this.nextPageInfo,
}) : super(key: key);
final NextPageInfo nextPageInfo;
@override
_AWidgetState createState() => _AWidgetState();
}
- Check it in the
initStatemethod and if there is some nextPageInfo - listen for it:
@override
void initState() {
super.initState();
if (null != widget.nextPageInfo) {
switch (widget.nextPageInfo.routeName) {
case '/next':
awaitNextPageResult(widget.nextPageInfo.resultFuture);
break;
}
}
}
Future<void> awaitNextPageResult(Future resultFuture) async {
final result = await resultFuture;
// do some work with the result
}
- Also you may want to rewrite initial B widget initialization code:
awaitNextPageResult(
Navigator.of(context).pushNamed(
"/next",
arguments: SomeArgs(),
),
);