在Android中 页面从栈里面回到前台显示 有固定的生命周期方法 onReume(),虽然在flutter也有widget生命周期方法,但是功能和onResume()方法相差比较大,并不能监听路由栈回退。但是往往我们需要在页面再次可见的时候在生命周期中做数据的刷新,flutter并没有封装好的生命周期方法给我们使用,很尴尬。利用NavigatorObserver、strean流和mixin撸一个吧
直接撸代码吧
//工具类
class RouteInfo {
Route currentRoute;
List<Route> routes;
RouteInfo(this.currentRoute, this.routes);
@override
String toString() {
return 'RouteInfo{currentRoute: $currentRoute, routes: $routes}';
}
}
class NavigationUtil extends NavigatorObserver{
static NavigationUtil _instance;
static Map<String, WidgetBuilder> configRoutes = {
SplashPage.sName: (_) => SplashPage(),
CustomerServiceCenterApp.sName: (_) => CustomerServiceCenterApp(),
};
//进入路由
@override
void didPush(Route route, Route previousRoute) {
super.didPush(route, previousRoute);
if (_routeInfo == null) {
_routeInfo = new RouteInfo(null, new List<Route>());
}
print('----------push-----------');
print('---------当前活动的路由:${route.settings}');
print('---------先前活动的路由:${previousRoute?.settings}');
print('----------end-----------');
///这里过滤调push的是dialog的情况
if (route is CupertinoPageRoute || route is MaterialPageRoute) {
_routeInfo.routes.add(route);
routeObserver();
}
}
//用新路由替换旧路由
@override
void didReplace({Route newRoute, Route oldRoute}) {
super.didReplace();
print('----------didReplace-----------');
print('---------当前活动的路由:${newRoute.settings}');
print('---------先前活动的路由:${oldRoute?.settings}');
print('----------end-----------');
if (newRoute is CupertinoPageRoute || newRoute is MaterialPageRoute) {
_routeInfo.routes.remove(oldRoute);
_routeInfo.routes.add(newRoute);
routeObserver();
}
}
//弹出路由
@override
void didPop(Route route, Route previousRoute) {
print('----------didPop-----------');
print('---------当前活动的路由:${route.settings}');
print('---------先前活动的路由:${previousRoute?.settings}');
print('----------end-----------');
super.didPop(route, previousRoute);
if (route is CupertinoPageRoute || route is MaterialPageRoute) {
_routeInfo.routes.remove(route);
routeObserver();
}
}
//删除路由
@override
void didRemove(Route removedRoute, Route oldRoute) {
print('----------didRemove-----------');
print('---------当前活动的路由:${removedRoute.settings}');
print('---------先前活动的路由:${oldRoute?.settings}');
super.didRemove(removedRoute, oldRoute);
if (removedRoute is CupertinoPageRoute || removedRoute is MaterialPageRoute) {
_routeInfo.routes.remove(removedRoute);
routeObserver();
}
}
void routeObserver() {
_routeInfo.currentRoute = _routeInfo.routes.last;
navigatorState = _routeInfo.currentRoute.navigator;
L.d(_routeInfo.toString(), 'NavigationUtil');
_streamController.sink.add(_routeInfo);
}
}
//约束类
mixin NavigationMixin<T extends StatefulWidget> on State<T> {
StreamSubscription<RouteInfo> streamSubscription;
Route lastRoute;
@override
void initState() {
super.initState();
streamSubscription = NavigationUtil.getInstance().streamController.stream.listen((RouteInfo routeInfo) {
if (routeInfo.currentRoute.settings.name == routName) {
onFocus();
}
/// 第一次监听到路由变化
if (lastRoute == null) {
onBlur();
}
/// 上一个是该页面,新的路由不是该页面
if (lastRoute?.settings?.name == routName && routeInfo.currentRoute.settings.name != routName) {
onBlur();
}
lastRoute = routeInfo.currentRoute;
});
}
@override
void dispose() {
super.dispose();
streamSubscription?.cancel();
streamSubscription = null;
}
@protected
String get routName;
@protected
void onBlur() {
}
@protected
void onFocus() {
}
}
好了!关键类有了,接下来就是使用。如图
第一步:navigatorObservers在MaterialApp 使用
第二步:在page的widget中继承。传入当前的路由名称,然后重写方法就好