Flutter 有內建一個路由管理 API Navigator
,而Flutter也在今年發表了 Navigator 2.0 但因為工作上是使用 fluro 這個路由管理套件,所以就沒特別研究了 Navigator 2.0,只能大概說明一下 Navigator 1.0
用起來算是很簡單,我們可以直接用 Navigator.push
裡面會就放我們要打開的新頁面。
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return NewRoute();
}),
);
但為了方便管理通常都會使用命名路由的方式,然後將原本的 home:
換成 '/': (context) => const MyHomePage()
MaterialApp(
routes: {
'/': (context) => const MyHomePage(),
'users_list': (context) => const UsersListPage(),
},
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
如果要到另外一個頁面就是使用 Navigator.pushNamed
Navigator.pushNamed(context, 'users_list');
但對於一些動態路由或者需要傳參數的頁面就會有點麻煩,所以大部分都會使用路由管理套件,雖然工作上是使用 fluro但架設起來也是有點龐大,所以就決定試玩一下另外一個套件 auto_route
dependencies:
auto_route: ^2.4.2
dev_dependencies:
auto_route_generator: ^2.4.1
先建立另外一個檔案 router.dart
import 'package:auto_route/auto_route.dart';
import 'package:flutter_rest_api_playground/view/users/users_detail_page.dart';
import 'package:flutter_rest_api_playground/view/users/users_list_page.dart';
import '../main.dart';
@MaterialAutoRouter(
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(page: MyHomePage, path: '/', initial: true),
AutoRoute(page: UsersListPage, path: '/users'),
AutoRoute(page: UserDetailPage, path: '/user/:id'),
],
)
class $AppRouter {}
註冊路由就是會用 AutoRoute
裡面頁面以及路由,首頁的話就加上 initial: true
,而如果需要動態路由就可以 :
來標示,整體看起來跟網頁很像。
replaceInRouteName
則是將我們的所註冊的頁面輸出成另外一個名字避免混淆,這樣讓我們 push
時就會是使用 UsersListRoute
而不是 UsersListPage
。
因為auto_run會需要使用 codegen 所以一樣要跑 build_runner。
使用時就將 MaterialApp
改為 MaterialApp.router
,然後實例化 AppRouter
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _appRouter = AppRouter();
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: AutoRouterDelegate(_appRouter),
routeInformationParser: _appRouter.defaultRouteParser(),
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
}
}
要導轉頁面時也算蠻簡單的:
AutoRouter.of(context).pushNamed('/users');
AutoRouter.of(context).push(UsersListRoute());
可以選擇要直接使用註冊的 path
或者是 codegen出來的 xxxxxRoute
而需要接收參數的頁面的宣告也很直觀
class UserDetailPage extends StatefulWidget {
const UserDetailPage({Key? key, @PathParam('id') required this.userId})
: super(key: key);
final String userId;
@override
State<UserDetailPage> createState() => _UserDetailPageState();
}
加上 @PathParam
即可, ()
放我們在註冊時的 :
的命名,所以以這個例子來說就是使用
@PathParam('id')
並把傳給 userId
使用上就直接在字串中加入我們的變數或者使用 UserDetailRoute
裡面傳參數
AutoRouter.of(context).pushNamed('/user/${userInfo.id}');
AutoRouter.of(context).push(UserDetailRoute(userId: userInfo.id.toString()));
寫到今天突然發現好像快沒有東西可以寫了, 明天可能會試著玩玩其他狀態管理框架。
今天的程式碼:
https://github.com/zxc469469/flutter_rest_api_playground/tree/Day25
參考資料: