Skip to main content

03 使用navigator2.0路由来管理多个页面

1 navigator2.0是什么? 为什么要用它?它解决了什么问题?

navigator2.0是用于管理flutter页面的路由管理器。相较于之前的1.0版本,当前的2.0版本 也能应用于flutterweb端;可以看成是navigator2.0是把weburl概念的实现,然后用于 flutter中,而已。
那么为什么要用它呢?它解决了什么问题?一个强大的app往往有大量的界面,而navigator2就是以路由的 概念在管理这些界面。

2 demon

main.dart
import 'package:driver/model/order_model.dart';
import 'package:driver/pages/home_page.dart';
import 'package:driver/pages/order_detail_page.dart';
import 'package:flutter/material.dart';

void main() {
runApp(const App());
}
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);


State<App> createState() => _AppState();
}

class _AppState extends State<App> {
final AppRouterDelegate _routerDelegate = AppRouterDelegate();
final AppRouteInformationParser _routeInformationParser = AppRouteInformationParser();


Widget build(BuildContext context) {
print('_BiliAppState:build');
//定义route
var widget = Router(
routeInformationParser: _routeInformationParser,
routerDelegate: _routerDelegate,

///routeInformationParser为null时可缺省,routeInformation提供者
routeInformationProvider: PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation(location: '/')),
);
return MaterialApp(home: widget);
}
}

///可缺省,主要应用与web,持有RouteInformationProvider 提供的 RouteInformation ,可以将其解析为我们定义的数据类型。
class AppRouteInformationParser extends RouteInformationParser<RoutePath> {

Future<RoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
final uri = Uri.parse(routeInformation.location!);
print('BiliRouteInformationParser:parseRouteInformation:uri:$uri');
if (uri.pathSegments.isEmpty) {
return RoutePath.home();
}
return RoutePath.orderDetail();
}
}

class RoutePath {
final String location;

RoutePath.home(): location = '/';

RoutePath.orderDetail(): location = '/orderDetail';
}

class AppRouterDelegate extends RouterDelegate<RoutePath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<RoutePath> {
final GlobalKey<NavigatorState> navigatorKey;
late RoutePath path;
List<MaterialPage> pages = [];
OrderModel? orderModel;

//为Navigator设置一个key,必要的时候可以通过navigatorKey.currentState来获取到NavigatorState对象
AppRouterDelegate(): navigatorKey = GlobalKey<NavigatorState>();


Widget build(BuildContext context) {
//构建路由栈
pages = [
pageWrap(HomePage(
onJumpOrderDetail: (mo) {
orderModel = mo;
notifyListeners();
},
)),
if (orderModel != null)
pageWrap(
OrderDetailPage(orderModel: orderModel!)
)
];
print('BiliRouterDelegate:build');
return Navigator(
key: navigatorKey,
pages: pages,
onPopPage: (route, result) {
print('Navigator:onPopPage');
//在这里可以控制是否可以返回
if (!route.didPop(result)) {
return false;
}
return true;
},
);
}

//路由初始化时,Router 会调用setNewRoutePath 方法来更新应用程序的路由状态:

Future<void> setNewRoutePath(RoutePath path) async {
print('BiliRouterDelegate:setNewRoutePath:$path');
this.path = path;
}
}

///创建Page
pageWrap(Widget child) {
return MaterialPage(
key: ValueKey(child.hashCode),
child: child,
);
}
pages/home_page.dart
import 'package:flutter/material.dart';

import '../model/order_model.dart';

class HomePage extends StatefulWidget {
final ValueChanged<OrderModel> onJumpOrderDetail;
const HomePage({Key? key, required this.onJumpOrderDetail}) : super(key: key);


State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {



Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Column(
children: [
Text('首页'),
MaterialButton(
onPressed: () => widget.onJumpOrderDetail(OrderModel(1)),
child: const Text('详情'),
)

],
),
),
);
}
}
pages/order_detail_page.dart
import 'package:driver/model/order_model.dart';
import 'package:flutter/material.dart';

class OrderDetailPage extends StatefulWidget {
final OrderModel orderModel;
const OrderDetailPage({Key? key, required this.orderModel}) : super(key: key);


State<OrderDetailPage> createState() => _OrderDetailPageState();
}

class _OrderDetailPageState extends State<OrderDetailPage> {

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Text("order detail ${widget.orderModel.id}"),
),
);
}
}
model/order_model.dart
class OrderModel {
final int id;

OrderModel(this.id);
}