Getx
https://pub.flutter-io.cn/packages/get
vscode 插件
Android Studio/Intellij 插件
本节目标
- GetPage 对象
- 路由层级控制
- 路由中间件、鉴权
- 404 处理
- 路由跳转、替换、清除
- 路由传值、返回值
- 路由转场动画
开发环境
- Flutter 2.1.0-12.1.pre
- Dart 2.13.0
- get: ^3.26.0
参考
视频
https://www.bilibili.com/video/BV1yU4y1876r/
代码
https://github.com/ducafecat/getx_quick_start
正文
初始 getx 项目
1 2 3
| dependencies: ... get: ^3.26.0
|
- lib/pages/home/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import 'package:flutter/material.dart'; import 'package:get/get.dart';
class HomeView extends StatelessWidget { const HomeView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("首页"), ), body: ListView( children: [ Divider(),
], ), ); } }
|
- lib/common/routes/app_routes.dart
1 2 3 4 5
| part of 'app_pages.dart';
abstract class AppRoutes { static const Home = '/home'; }
|
- lib/common/routes/app_pages.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import 'package:get/get.dart';
part 'app_routes.dart';
class AppPages { static const INITIAL = AppRoutes.Home;
static final routes = [ GetPage( name: AppRoutes.Home, page: () => HomeView(), ), ]; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Future<void> main() async { runApp(MyApp()); }
class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return GetMaterialApp( debugShowCheckedModeBanner: false, initialRoute: AppPages.INITIAL, getPages: AppPages.routes, ); } }
|
编写 GetPage 定义
- lib/pages/list/index.dart
1 2 3 4 5 6 7 8 9 10 11 12
| class ListView extends StatelessWidget { const ListView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("列表页"), ), ); } }
|
- lib/pages/list_detail/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class DetailView extends StatelessWidget { const DetailView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("详情页"), ), body: ListView( children: [ ListTile( title: Text("导航-返回"), subtitle: Text('Get.back()'), onTap: () => Get.back(), ), ], ), ); } }
|
- lib/common/routes/app_routes.dart
1 2 3 4
| abstract class AppRoutes { static const Home = '/home'; static const List = '/list'; static const Detail = '/detail';
|
- lib/common/routes/app_pages.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| GetPage( name: AppRoutes.Home, page: () => HomeView(), children: [ GetPage( name: AppRoutes.List, page: () => ListView(), children: [ GetPage( name: AppRoutes.Detail, page: () => DetailView(), ), ], ), ], ),
|
导航操作 命名、视图对象
- lib/pages/home/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ListTile( title: Text("导航-命名路由 home > list"), subtitle: Text('Get.toNamed("/home/list")'), onTap: () => Get.toNamed("/home/list"), ), ListTile( title: Text("导航-命名路由 home > list > detail"), subtitle: Text('Get.toNamed("/home/list/detail")'), onTap: () => Get.toNamed("/home/list/detail"), ), ListTile( title: Text("导航-类对象"), subtitle: Text("Get.to(DetailView())"), onTap: () => Get.to(DetailView()), ),
|
导航-清除上一个
- lib/pages/home/index.dart
1 2 3 4 5
| ListTile( title: Text("导航-清除上一个"), subtitle: Text("Get.off(DetailView())"), onTap: () => Get.off(DetailView()), ),
|
导航-清除所有
- lib/pages/home/index.dart
1 2 3 4 5
| ListTile( title: Text("导航-清除所有"), subtitle: Text("Get.offAll(DetailView())"), onTap: () => Get.offAll(DetailView()), ),
|
导航-arguments 传值+返回值
- lib/pages/home/index.dart
1 2 3 4 5 6 7 8 9 10
| ListTile( title: Text("导航-arguments传值+返回值"), subtitle: Text( 'Get.toNamed("/home/list/detail", arguments: {"id": 999})'), onTap: () async { var result = await Get.toNamed("/home/list/detail", arguments: {"id": 999}); Get.snackbar("返回值", "success -> " + result["success"].toString()); }, ),
|
- lib/pages/list_detail/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| _buildBackListTileRow(Map? val) { return val == null ? Container() : ListTile( title: Text("传值 id = " + val["id"].toString()), subtitle: Text('Get.back(result: {"success": true}'), onTap: () => Get.back(result: {"success": true}), ); }
@override Widget build(BuildContext context) { final details = Get.arguments as Map; final parameters = Get.parameters;
return Scaffold( appBar: AppBar( title: Text("详情页"), ), body: ListView( children: [ ListTile( title: Text("导航-返回"), subtitle: Text('Get.back()'), onTap: () => Get.back(), ), _buildBackListTileRow(details), _buildBackListTileRow(parameters), ], ), ); }
|
导航-parameters 传值+返回值
- lib/pages/home/index.dart
1 2 3 4 5 6 7 8
| ListTile( title: Text("导航-parameters传值+返回值"), subtitle: Text('Get.toNamed("/home/list/detail?id=666")'), onTap: () async { var result = await Get.toNamed("/home/list/detail?id=666"); Get.snackbar("返回值", "success -> " + result["success"].toString()); }, ),
|
- lib/pages/list_detail/index.dart
1 2 3
| @override Widget build(BuildContext context) { final parameters = Get.parameters;
|
导航-参数传值+返回值
- lib/common/routes/app_routes.dart
1
| static const Detail_ID = '/detail/:id';
|
- lib/common/routes/app_pages.dart
1 2 3 4 5
| ... GetPage( name: AppRoutes.Detail_ID, page: () => DetailView(), ),
|
- lib/pages/home/index.dart
1 2 3 4 5 6 7 8
| ListTile( title: Text("导航-参数传值+返回值"), subtitle: Text('Get.toNamed("/home/list/detail/777")'), onTap: () async { var result = await Get.toNamed("/home/list/detail/777"); Get.snackbar("返回值", "success -> " + result["success"].toString()); }, ),
|
导航-not found
- lib/pages/notfound/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class NotfoundView extends StatelessWidget { const NotfoundView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("路由没有找到"), ), body: ListTile( title: Text("返回首页"), subtitle: Text('Get.offAllNamed(AppRoutes.Home)'), onTap: () => Get.offAllNamed(AppRoutes.Home), ), ); } }
|
- lib/common/routes/app_routes.dart
1
| static const NotFound = '/notfound';
|
- lib/common/routes/app_pages.dart
1 2 3 4
| static final unknownRoute = GetPage( name: AppRoutes.NotFound, page: () => NotfoundView(), );
|
1 2 3 4 5 6 7
| @override Widget build(BuildContext context) { return GetMaterialApp( ... unknownRoute: AppPages.unknownRoute, ); }
|
导航-中间件-认证 Auth
- lib/pages/login/index.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class LoginView extends StatelessWidget { const LoginView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("登录"), ), body: ListTile( title: Text("返回首页"), subtitle: Text('Get.offAllNamed(AppRoutes.Home)'), onTap: () => Get.offAllNamed(AppRoutes.Home), ), ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class MyView extends StatelessWidget { const MyView({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("我的"), ), body: ListTile( title: Text("返回首页"), subtitle: Text('Get.offAllNamed(AppRoutes.Home)'), onTap: () => Get.offAllNamed(AppRoutes.Home), ), ); } }
|
- lib/common/routes/app_routes.dart
1 2
| static const Login = '/login'; static const My = '/my';
|
- lib/common/middleware/router_auth.dart
1 2 3 4 5 6 7 8 9 10 11 12
| class RouteAuthMiddleware extends GetMiddleware { @override int priority = 0;
RouteAuthMiddleware({required this.priority});
@override RouteSettings? redirect(String route) { Future.delayed(Duration(seconds: 1), () => Get.snackbar("提示", "请先登录APP")); return RouteSettings(name: AppRoutes.Login); } }
|
- lib/common/routes/app_pages.dart
1 2 3 4 5 6 7 8 9 10 11 12 13
| GetPage( name: AppRoutes.Login, page: () => LoginView(), ),
GetPage( name: AppRoutes.My, page: () => MyView(), middlewares: [ RouteAuthMiddleware(priority: 1), ], ),
|
- lib/pages/home/index.dart
1 2 3 4 5
| ListTile( title: Text("导航-中间件-认证Auth"), subtitle: Text('Get.toNamed(AppRoutes.My)'), onTap: () => Get.toNamed(AppRoutes.My), ),
|
Transition 转场动画
- lib/common/routes/app_pages.dart
1 2 3 4 5
| GetPage( name: AppRoutes.Detail_ID, page: () => DetailView(), transition: Transition.downToUp, ),
|
© 猫哥
https://ducafecat.tech
https://ducafecat.gitee.io
邮箱 ducafecat@gmail.com / 微信 ducafecat / 留言板 disqus