🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Flutter学习
🌠 首发时间:2024年5月30日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
目录
状态管理
通俗地讲:当我们想在多个界面(组件 / Widget)之间共享状态(数据),或者一个页面(组件 / Widget)中的多个子组件之间共享状态(数据),这个时候我们就可以用 Flutter 中的状态管理来管理统一的状态(数据),实现不同组件之间的传值和数据共享。
现在 Flutter 的状态管理方案很多,如 redux、bloc、state、provider、Getx 等。
provider 是官方提供的状态管理解决方案,主要功能就是状态管理。而 Getx 是第三方的状态管理插件,不仅具有状态管理的功能,还具有路由管理、主题管理、国际化多语言管理、Obx 局部更新、网络请求、数据验证等功能,相比于其它状态管理插件,Getx 更简单、功能强大并且高性能。
Getx介绍
GetX 是 Flutter 上的一个轻量且强大的解决方案,Getx 为我们提供了高性能的状态管理、智能的依赖注入和便捷的路由管理。
-
GetX 有 3 个基本原则:
- 性能:GetX 专注于性能和最小资源消耗。GetX 打包后的 apk 占用大小和运行时的内存占用与其他状态管理插件不相上下
- 效率:Getx 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长
- 结构:GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护
-
GetX 并不臃肿,却很轻量。如果你只使用状态管理,只有状态管理模块会被编译,其他没用到的东西都不会被编译到你的代码中。它拥有众多的功能,但这些功能都在独立的容器中,只有在使用后才会启动。
-
Getx 有一个庞大的生态系统,能够在 Android、iOS、Web、Mac、Linux、Windows 和你的服务器上用同样的代码运行。 通过 Get server 可以在你的后端完全重用你在前端写的代码。
-
官网:https://pub-web.flutter-io.cn/packages/get

-
中文文档:https://github.com/jonataslaw/getx/blob/master/README.zh-cn.md

Getx中的Dialog以及改变主题
Getx安装
引入依赖:
dependencies:
get: ^4.6.6
在需要用到的文件中导入,它将被使用:
import 'package:get/get.dart';
defaultDialog组件
在 GetX 框架中,defaultDialog是用于显示对话框的默认方法。它有以下参数:
-
title:对话框的标题(可选)- 用于显示在对话框顶部的标题文本。
- 默认值为
null,表示不显示标题。
-
content:对话框的内容(可选)- 存储在对话框中间的信息。
- 可以是一个文本字符串或一个 Widget。
- 默认值为
null,表示不显示内容。
-
textConfirm:确认按钮的文本(可选)- 用于在确认按钮上显示的文本。
- 默认值为
"OK"。
-
textCancel:取消按钮的文本(可选)- 用于在取消按钮上显示的文本。
- 默认值为
"Cancel"。
-
confirmTextColor:确认按钮文本的颜色(可选)- 确认按钮上文本的颜色。
- 可以是一个颜色字符串或一个颜色对象。
- 默认值为
null,使用平台默认颜色。
-
cancelTextColor:取消按钮文本的颜色(可选)- 取消按钮上文本的颜色。
- 可以是一个颜色字符串或一个颜色对象。
- 默认值为
null,使用平台默认颜色。
-
barrierDismissible:是否允许通过点击对话框外部来关闭对话框(可选)- 如果设置为
true,则用户可以通过点击对话框外部来关闭它。 - 如果设置为
false,则用户必须点击确认或取消按钮才能关闭对话框。 - 默认值为
true。
- 如果设置为
-
onConfirm:确认按钮被点击时的回调函数(可选)- 当用户点击确认按钮时调用的回调函数。
- 如果没有提供,则表示不需要处理确认事件。
-
onCancel:取消按钮被点击时的回调函数(可选)- 当用户点击取消按钮时调用的回调函数。
- 如果没有提供,则表示不需要处理取消事件。
import 'package:flutter/material.dart';
import 'package:get/get.dart'; //导入
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
//改为使用GetMaterialApp
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//Flutter默认的dialog, 代码繁杂
void _alertDialog(context) async {
await showDialog(
barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框
context: context,
builder: (context) {
return AlertDialog(
title: const Text("提示信息!"),
content: const Text("您确定要删除吗"),
actions: [
TextButton(
onPressed: () {
Navigator.of(context)
.pop("确定"); //点击按钮让AlertDialog消失, 同时返回“确定”
},
child: const Text("确定")),
TextButton(
onPressed: () {
Navigator.of(context).pop("取消");
},
child: const Text("取消"))
],
);
},
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Getx'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_alertDialog(context);
},
child: const Text('Flutter默认的dialog'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {
//Getx对dialog进行了封装
Get.defaultDialog(
title: "提示信息!",
middleText: "您确定要删除吗?",
confirm: ElevatedButton(
onPressed: () {
Get.back(); //Getx对路由也进行了封装
},
child: const Text("确定"),
),
cancel: ElevatedButton(
onPressed: () {
Get.back();
},
child: const Text("取消"),
),
);
},
child: const Text('Getx的defaultDialog'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {},
child: const Text('Getx的snackbar'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {},
child: const Text('Getx bottomSheet切换主题'),
),
],
),
),
);
}
}

snackbar组件
Snackbar 和我们前面讲的 toast 有点相似,如果想在应用程序中触发某些特定的事件后,需要弹出快捷消息,那么使用 snackbar 则是最佳的选择。
我们可以通过 Get.snackbar() 来显示 snackbar,如下所示
ElevatedButton(
onPressed: () {
Get.snackbar(
"提示",
"你有一条新的信息",
backgroundColor: Colors.blue[200],
colorText: Colors.white,
snackPosition: SnackPosition.TOP,
);
},
child: const Text('Getx的snackbar'),
),

Getx bottomSheet切换主题
ElevatedButton(
onPressed: () {
Get.bottomSheet(Container(
color: Get.isDarkMode ? Colors.black : Colors.white,
height: 200,
child: Column(
children: [
ListTile(
leading: Icon(
Icons.wb_sunny_outlined,
color: Get.isDarkMode ? Colors.white : Colors.black,
),
onTap: () {
Get.changeTheme(ThemeData.light());
Get.back();
},
title: Text(
"白天模式",
style: TextStyle(
color: Get.isDarkMode ? Colors.white : Colors.black,
),
),
),
ListTile(
leading: Icon(
Icons.wb_sunny,
color: Get.isDarkMode ? Colors.white : Colors.black,
),
onTap: () {
Get.changeTheme(ThemeData.dark());
Get.back();
},
title: Text(
"黑夜模式",
style: TextStyle(
color: Get.isDarkMode ? Colors.white : Colors.black,
),
),
)
],
),
));
},
child: const Text('Getx bottomSheet切换主题'),
),


Getx路由管理
Getx 为我们封装了 Navigation,无需 context 可进行跳转,使用 Getx 进行路由跳转非常的简单,只需要调用 Get.to() 即可进行路由跳转, Getx 路由跳转简化了跳转动画设置、动画时长定义、动画曲线设置。
Get.to()实现普通路由跳转
ps:需要引入跳转页面的组件
Get.to(() => Nextscreen());
Get.toNamed()跳转到其它页面
Get.toNamed("/login");
Get.toNamed("/shop", arguments: {
"id": 20,
});
Get.back()返回到上一级页面
Get.back();
Get.offAI()返回到根
ps:需要引入根页面的组件
Get.offAll(const Tabs(index: 4));
Get.off(Nextscreen())
进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等)
ps:需要引入跳转页面的组件
Get.off(Nextscreen());
defaultTransition可以配置默认动画
通过设置 GetMaterialApp 的参数 defaultTransition,可以配置页面跳转的默认动画。
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
initialRoute: "/",
defaultTransition: Transition.rightToLeft,
);
}
}
GetPage 可以配置动态路由
通过 getPages 参数来配置动态路由
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
initialRoute: "/",
defaultTransition: Transition.rightToLeft,
getPages: [
GetPage(name: "/", page: () => const Tabs()),
GetPage(
name: "/login",
page: () => const LoginPage(),
transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
),
],
);
}
}
Getx 路由跳转传值以及接受数据
-
路由配置中不需要再传参
-
跳转传值不变:
Get.toNamed("/shop", arguments: { "id":20 }); -
在跳转的页面中,我们只需要通过
Get.arguments即可接收到数据
将路由抽离
router.dart
import 'package:get/get.dart';
import '../pages/tabs/home.dart';
import '../pages/tabs.dart';
class AppPage {
static final routes = [
GetPage(name: "/", page: () => const Tabs()),
GetPage(
name: "/home",
page: () => const HomePage(),
transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
),
];
}
main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import './routers/router.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
initialRoute: "/",
defaultTransition: Transition.rightToLeft,
getPages: AppPage.routes,
);
}
}
Getx 中间件配置
在 GetX 框架中,中间件(Middleware)是一种机制,可以让开发者在页面路由、导航等过程中添加额外的逻辑处理。中间件能够拦截并处理路由跳转、导航事件等,为应用程序提供更多的灵活性和控制。
在 GetX 框架中,中间件可以用来执行诸如日志记录、权限检查、数据加载等操作。通过中间件,你可以在页面跳转前后、导航事件触发时执行特定的逻辑,而无需直接修改页面代码。
比如,我们自己写一个中间件
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
class HomeMiddleware extends GetMiddleware {
RouteSettings? redirect(String? route) {
print(route);
// return null; //表示不做任何操作, 跳转到以前的路由
return const RouteSettings(name: "/category", arguments: {}); //跳转到对应的页面
}
}
在 GetPage 中可以配置中间件
import 'package:get/get.dart';
import '../middleware/homeMiddleware.dart';
import '../pages/tabs/category.dart';
import '../pages/tabs/home.dart';
import '../pages/tabs.dart';
class AppPage {
static final routes = [
GetPage(name: "/", page: () => const Tabs()),
GetPage(
name: "/home",
page: () => const HomePage(),
transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
middlewares: [HomeMiddleware()], //中间件
),
GetPage(name: "/category", page: () => const CategoryPage()),
];
}
3508

被折叠的 条评论
为什么被折叠?



