03 使用navigator2.0路由来管理多个页面
1 navigator2.0是什么? 为什么要用它?它解决了什么问题?
navigator2.0
是用于管理flutter
页面的路由管理器。相较于之前的1.0
版本,当前的2.0
版本
也能应用于flutter
的web
端;可以看成是navigator2.0
是把web
的url
概念的实现,然后用于
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);
}