Flutter插件Get(3):路由管理篇.md
一、前言
GetX 为我们封装了 Navigation ,无需 context 可进行跳转,使用 GetX 进行路由跳转非常的简单,只需要调用Get.to()
等即可进行路由跳转。以下是其一些用法:
方法 | 功能 |
---|---|
Get.to() |
跳转新页面 |
Get.toNamed() |
命名路由跳转 |
Get.back() |
路由返回 |
Get.off() |
进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等) |
Get.offAll() |
进入下一个页面并取消之前的所有路由 |
Get.offAndToNamed() |
跳转并使用下一个路由替换当前路由页面(可用于关闭中间页面,如搜索页面) |
Get.removeRoute() |
删除一个路由 |
Get.until() |
反复返回,直到表达式返回真 |
Get.offUntil() |
转到下一条路由,并删除所有之前的路由,直到表达式返回true |
Get.offNamedUntil() |
转到下一个命名的路由,并删除所有之前的路由,直到表达式返回true |
Get.arguments |
获取当前路由页面的参数 |
Get.previousRoute |
获取之前的路由名称 |
Get.rawRoute |
给出要访问的原始路由 |
Ok, 这些只是一部分,你可以到官方网站查看更多详细的用法,下面说下具体的使用。
先看下综合示例效果图,程序下载(Git 下载地址):
二、普通路由导航
2.1 示例
(1)设置应用程序入口
当我们导入依赖后,在应用程序顶层把 GetMaterialApp 作为顶层,如下所示:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp( // 修改为GetMaterialApp
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: const Text("GetX Title"),
),
body: const MyHomePage(),
),
);
}
}
MyHomePage 类在后面实现。
(2)创建一个新的页面文件
然后,在lib
目录下创建一个名为nextScreenPage.dart
的文件:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NextScreenPage extends StatelessWidget {
const NextScreenPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("新页面"),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Get.back(); // 返回到前一页
},
child: const Text("返回上一个页面")),
),
);
}
}
同时,使用了Get.back()
方法,按下按钮可以返回到前一页,一般都与Get.to()
一起使用。
(3)调用to方法切换路由
import 'package:custom/nextScreenPage.dart';
ElevatedButton(
onPressed: () async {
Get.to(const NextScreenPage()); // to方法实现页面跳转
},
child: const Text("普通路由跳转")),
包含这个按钮的完整 MyHomePage 类实现如下:
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
Get.to(const NextScreenPage()); // to方法实现页面跳转
},
child: const Text("普通路由跳转")),
],
),
);
}
}
使用了Get.to()
方法,按下按钮可以调整到指定的页面。
2.2 GetX用法与原生路由的对比
(1)打开到新的页面:
Get.to(NextScreen());
对应原生路由:
Navigator.push(context, MaterialPageRoute<void>(
builder: (BuildContext context) {
return NextScreen();
},
));
(2)返回:
Get.back();
对应原生路由:
Navigator.pop(context);
(3)打开新页面,并且用新页面替换旧页面(删除旧页面):
Get.off(NextScreen());
对应原生路由:
Navigator.pushReplacement(context, MaterialPageRoute<void>(
builder: (BuildContext context) {
return NextScreen();
},
));
(4)打开新页面并删除之前的所有路由:
Get.offAll(NextScreen());
对应原生路由:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) {
return NextScreen();
},
),
(Route<dynamic> route) => false,
);
(5)导航到新页面,在返回时接收返回数据:
var data = await Get.to(NextScreen());
对应原生路由:
var data = await Navigator.push(context, MaterialPageRoute<void>(
builder: (BuildContext context) {
return NextScreen();
},
));
(6)带返回值返回前一个路由,配合上面使用:
Get.back(result: 'success');
对应原生路由:
Navigator.pop(context, 'success');
三、别名路由导航
3.1 别名路由定义
(1)声明别名:
abstract class Routes {
static const Home = '/';
static const NextScreen = '/NextScreen';
}
(2)注册路由表:
abstract class AppPages {
static final pages = [
GetPage(
name: Routes.Home,
page: () => const MyHomePage(),
),
GetPage(
name: Routes.NextScreen,
page: () => const NextScreenPage(),
),
];
}
(3)替换MaterialApp为GetMaterialApp:
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: const Text("GetX Title"),
),
body: const MyHomePage(),
),
);
}
}
3.2 示例
假如我们有一个 NextScreenPage 页面,使用别名路由的时候,上面示例中 MyApp 类修改如下:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: const Text("GetX Title"),
),
body: const MyHomePage(),
),
// 主页面路由
initialRoute: Routes.Home,
// 注册路由表
getPages: AppPages.pages,
);
}
}
然后调用Get.toNamed()
跳转到命名路由,上面示例中的 MyHomePage 类修改如下:
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//......
// 别名路由跳转
ElevatedButton(
onPressed: () async {
Get.toNamed(Routes.NextScreen); // toNamed方法实现页面跳转
},
child: const Text("别名路由跳转")),
],
),
);
}
}
3.3 GetX用法与原生路由的对比
(1)导航到下一个页面:
Get.toNamed(Routes.NextScreen);
(2)导航到下一个页面并删除前一个页面:
Get.offNamed(Routes.NextScreen);
(3)导航到下一个页面并删除以前所有的页面:
Get.offAllNamed(Routes.NextScreen);
四、别名路由传值
通过 argument 传递参数,argument 接收字符串、Map、List、类的实例。
获取参数:
String name=Get.arguments;
4.1 创建一个新的页面文件
新建 valueTransferPage.dart 文件,作为接收页面,内容如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ValueTransferPage extends StatelessWidget {
const ValueTransferPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("别名路由传值页面"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(Get.arguments), // 别名路由传值,在这里接收
ElevatedButton(
onPressed: () {
Get.back();
},
child: const Text("返回上一个页面")),
],
),
);
}
}
4.2 通过 argument 传递参数
主页面修改如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:custom/next_screen_page.dart';
import 'package:custom/value_transfer_page.dart';
void main() {
runApp(const MyApp());
}
// 声明别名
abstract class Routes {
static const Home = '/';
static const NextScreen = '/NextScreen';
static const ValueTransfer = '/ValueTransfer';
}
// 注册路由表
abstract class AppPages {
static final pages = [
GetPage(
name: Routes.Home,
page: () => const MyHomePage(),
),
GetPage(
name: Routes.NextScreen,
page: () => const NextScreenPage(),
),
GetPage(
name: Routes.ValueTransfer,
page: () => const ValueTransferPage(),
),
];
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: const Text("GetX Title"),
),
body: const MyHomePage(),
),
// 主页面路由
initialRoute: Routes.Home,
// 注册路由表
getPages: AppPages.pages,
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 普通路由跳转
ElevatedButton(
onPressed: () async {
Get.to(const NextScreenPage()); // to方法实现页面跳转
},
child: const Text("普通路由跳转")),
// 别名路由跳转
ElevatedButton(
onPressed: () async {
Get.toNamed(Routes.NextScreen); // toNamed方法实现页面跳转
},
child: const Text("别名路由跳转")),
// 别名路由传值跳转
ElevatedButton(
onPressed: () async {
Get.toNamed(Routes.ValueTransfer,
arguments: "别名路由传值页面"); // toNamed方法带参数实现页面跳转
},
child: const Text("别名路由传值跳转")),
],
),
);
}
}
五、配置动画
defaultTransition 可以配置默认动画,修改上面示例如下:
// 注册路由表
abstract class AppPages {
static final pages = [
GetPage(
name: Routes.Home,
page: () => const MyHomePage(),
),
GetPage(
name: Routes.NextScreen,
page: () => const NextScreenPage(),
transition: Transition.rightToLeft, // 页面跳转动画
),
GetPage(
name: Routes.ValueTransfer,
page: () => const ValueTransferPage(),
transition: Transition.rightToLeft, // 页面跳转动画
),
];
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: const Text("GetX Title"),
),
body: const MyHomePage(),
),
defaultTransition: Transition.rightToLeftWithFade, // 配置默认动画
// 主页面路由
initialRoute: Routes.Home,
// 注册路由表
getPages: AppPages.pages,
);
}
}
六、路由抽离
当页面数目很多时,可以新建 routes.dart,将别名路由定义放在这个文件中:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:custom/nextScreenPage.dart';
import 'package:custom/valueTransferPage.dart';
// 声明别名
abstract class Routes {
static const Home = '/';
static const NextScreen = '/NextScreen';
static const ValueTransfer = '/ValueTransfer';
}
// 注册路由表
abstract class AppPages {
static final pages = [
GetPage(
name: Routes.Home,
page: () => const MyHomePage(),
),
GetPage(
name: Routes.NextScreen,
page: () => const NextScreenPage(),
//transition: Transition.rightToLeft, // 页面跳转动画
),
GetPage(
name: Routes.ValueTransfer,
page: () => const ValueTransferPage(),
//transition: Transition.rightToLeft, // 页面跳转动画
),
];
}
项目结构图如下:
参考:
Flutter状态管理终极方案GetX第一篇——路由 - 简书 (jianshu.com)
Flutter Getx 路由管理 - 鲤斌 - 博客园 (cnblogs.com)
Flutter中GetX的用法(超详细使用指南之路由管理篇)_flutter getx-CSDN博客