前言
学习教程:Getx教程_Flutter+Getx系列实战教程
简介
getX是第三方的状态管理插件,不仅具有状态管理的功能,还具有路由管理、主题管理、国际化多语言管理、网络请求、数据验证等功能。相比其他状态管理组件,getX简单、功能强大。
官方文档
https://pub-web.flutter-io.cn/packages/get
安装
flutter pub add get
将MaterialApp
修改为GetMaterialApp
GetMaterialApp(
title: 'getx',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'getx'),
);
Dialog、snackbar、bottomSheet
Dialog
ElevatedButton(
onPressed: () {
Get.defaultDialog(
title: "默认弹窗",
middleText: '弹出内容,你确定要卸载吗?',
confirm:
TextButton(onPressed: () {
Get.back();
}, child: const Text("确定")),
cancel:
TextButton(onPressed: () {
Get.back();
}, child: const Text("取消")));
},
child: const Text("getx 默认dialog"))
snackbar
ElevatedButton(
onPressed: () {
Get.snackbar("提示", "删除成功");
},
child: const Text("snack-bar"))
bottomSheet
ElevatedButton(
onPressed: () {
Get.bottomSheet(Container(
color: Colors.white,
height: 130,
child: Column(
children: [
ListTile(
leading: const Icon(Icons.wb_sunny_outlined),
title: const Text("白天模式"),
onTap: () {
Get.changeTheme(ThemeData.light());
Get.back();
},
),
const Divider(),
ListTile(
leading: const Icon(Icons.wb_sunny),
title: const Text("夜间模式"),
onTap: () {
Get.changeTheme(ThemeData.dark());
Get.back();
},
),
],
),
));
},
child: const Text("snack-bar"))
路由管理
GetX
为我们封装了Navigation
,无需context
可进行跳转。使用GetX
进行路由跳转更加的简单。只需要使用Get.to()
可进行路由跳转,GetX
对路由跳转简化了跳转动画设置、动画时长定义、动画曲线设置
我们可以通过Get.to()
实现普通的路由跳转,通过Get.toNamed
实现命名路由跳转,通过Get.back()
实现返回上一级路由,通过Get.ofAll()
返回跟路由,可以通过Get.off()
将当前页面从页面栈中移除,并将新的页面添加到页面栈中,可以通过Get.arguments
获取到路由传参
配置路由及路由动画
GetMaterialApp(
title: 'getx',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// home 和 initialRoute同时存在的话initialRoute会优先生效
home: const MyHomePage(title: 'getx'), // 主页
initialRoute: '/', // 默认显示的路由页面
defaultTransition: Transition.leftToRight, // 设置所有页面默认的路由跳转动画
getPages: [
//路由地址
GetPage(name: '/', page: () => const MyHomePage(title: 'getx')),
GetPage(
name: '/my',
page: () => const MyInfo(),
transition: Transition.leftToRight // 设置路由过度动画
)
],
)
Get.toNamed('my', arguments: {"message": 'Hello Flutter'});
Widget build(BuildContext context) {
String mes = Get.arguments?["message"] ?? '11';
return Scaffold(
appBar: AppBar(
title: const Text('我的'),
),
body: Center(
child: Text("个人信息:$mes"),
),
);
}
路由抽离
import 'package:test/page/my.dart';
import 'package:get/get.dart';
class AppPage {
static final List<GetPage<dynamic>> routes = [
GetPage(
name: '/my',
page: () => const MyInfo(),
transition: Transition.leftToRight // 设置路由过度动画
)
];
}
GetMaterialApp(
title: 'getx',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// home 和 initialRoute同时存在的话initialRoute会优先生效
home: const MyHomePage(title: 'getx'), // 主页// 默认显示的路由页面
defaultTransition: Transition.leftToRight, // 设置所有页面默认的路由跳转动画
getPages: AppPage.routes,
)
路由中间件(路由守卫)
import 'package:flutter/cupertino.dart';
import 'package:test/page/my.dart';
import 'package:get/get.dart';
class AppPage {
static final List<GetPage<dynamic>> routes = [
GetPage(
name: '/my',
page: () => const MyInfo(),
transition: Transition.leftToRight, // 设置路由过度动画
middlewares: [MyMiddleWare()])
];
}
// 中间件
class MyMiddleWare extends GetMiddleware {
// 重写重定向
redirect(route) {
String power = Get.arguments?['power'];
if (power == 'no') {
Get.snackbar("提示", "请先进行登录");
return const RouteSettings(name: 'login');
}
// 放行,跳转到目标路由
return null;
}
}
状态管理
主要用与多个页面共享状态使用,某一个页面的状态改变,其他页面也随着改变。
单页面状态管理
class _MyHomePageState extends State<MyHomePage> {
// 定义一个响应式的整数
RxInt count = 0.obs;
// 或者
RxInt a = RxInt(0);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
// const Color(0x00cab6ec)
body: Column(
children: [
ElevatedButton(
onPressed: () {
count.value += 1;
},
child: const Text("加1")),
// 监听值的变化
Obx(() => Text("当前值:${count.value}"))
],
),
);
}
}
如果使用过vue3
,那么接受起来就非常容易了。
优点:如果使用setState
会重新运行build
进行更新,如果内容过多的话,会产生较大的开销。使用Getx
只会更新你监听的组件,实现一个局部更新。
多页面状态管理
定义一个Controller
import 'package:get/get.dart';
class CountController extends GetxController {
// 定义响应式变量
RxInt count = 0.obs;
// 增加
void add() {
count.value++;
// 调用GetxController内置方法进行更新
update();
}
// 减少
void del() {
count.value--;
// 调用GetxController内置方法进行更新
update();
}
}
主页面使用
class _MyHomePageState extends State<MyHomePage> {
// 创建控制器示例
CountController countController =
Get.put(CountController(), tag: 'countController');
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
// const Color(0x00cab6ec)
body: Column(
children: [
ElevatedButton(
onPressed: () {
Get.toNamed('/my');
},
child: const Text("我的")),
ElevatedButton(
onPressed: () {
// 加1
countController.add();
},
child: const Text("加1")),
// 监听值的变化
Obx(() => Text("当前值:${countController.count.value}"))
],
),
);
}
}
其他页面使用
class MyInfoState extends State<MyInfo> {
// 获取示例
late final CountController countController;
void initState() {
super.initState();
countController = Get.find(tag: 'countController');
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('我的'),
),
body: Center(
child: ElevatedButton(
child: const Text("减1"),
onPressed: () {
countController.del();
},
),
),
);
}
}
GetX Binding
在我们所有使用Getx
状态管理器时,都需要手动创建一个示例,这样是是否麻烦的。而使用Binding可以在项目初始化时把需要使用的状态管理器统一进行初始化。
创建示例的几个方法
Get.put
,不使用控制器实例也会被创建Get.lazyPut
,懒加载方式创建实例,只有在使用时才会被创建Get.putAsync
,Get.put
的异步版本Get.create
,每次使用都会创建一个新的实例
创建绑定类
import 'package:get/get.dart';
import 'count_controller.dart';
class AllControllerBinding implements Bindings {
void dependencies() {
// 初始化
Get.lazyPut<CountController>(() => CountController());
// 多个则多执行几次Get.lazyPut
}
}
在main.dart中初始化
GetMaterialApp(
title: 'getx',
// 初始化绑定状态管理类
initialBinding: AllControllerBinding(),
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// home 和 initialRoute同时存在的话initialRoute会优先生效
home: const MyHomePage(title: 'getx'), // 主页// 默认显示的路由页面
defaultTransition: Transition.leftToRight, // 设置所有页面默认的路由跳转动画
getPages: AppPage.routes,
)
使用
初始化完成后,就不需要再进行创建。使用时只需要通过Get.find
来获取实例即可
CountController countController = Get.find<CountController>();
GetView
GetView
是GetX
框架中的一个重要组件,它主要用于简化页面组件的创建和管理。通过继承GetView
,可以方便地创建一个具有状态管理和路由导航功能的页面。
GetView的作用主要有以下几点:
-
简化页面的创建:继承
GetView
后,只需重写Widget build(BuildContext context)
方法即可创建页面,无需再手动创建StatefulWidget
或StatelessWidget
。 -
管理页面状态:
GetView
内部封装了GetX
框架提供的状态管理功能,可以轻松实现状态的监听、更新和销毁,避免了手动管理状态的繁琐操作。 -
路由导航:
GetView
提供了简单的路由导航功能,可以通过Get.to()
、Get.off()
等方法进行页面跳转,并且可以携带参数传递。 -
依赖注入:
GetView
内置了依赖注入功能,可以通过Get.put()
、Get.lazyPut()
等方法来注册和获取全局的依赖对象,方便在页面中使用。
总的来说,GetView
的作用是简化页面组件的创建和管理,提供了便捷的状态管理和路由导航功能,使得开发者可以更专注于业务逻辑的实现。
实例
// 需要指定要使用的状态管理类
class MyInfoPage extends GetView<CountController> {
const MyInfoPage({super.key});
Widget build(BuildContext context) {
// 如果第一次使用还需要put(没有结合Binding时)
Get.put(CountController());
return Scaffold(
appBar: AppBar(
title: const Text('我的'),
),
body: Center(
child: ElevatedButton(
child: const Text("减1"),
onPressed: () {
// 因为几次了GetView并且指定了泛型,因此可以获取到对应controller
controller.del();
},
),
),
);
}
}
几种使用情况:
- 只是单纯展示共享状态或者需要对共享状态操作
- 既有共享状态又有私有状态,这是可以结合响应式状态变量来使用。这样就不需要创建
StatefulWidget
以及其对应的State
多语言配置
略,可以自行观看视频。
工具类——GetUtils
GetUtils
是Getx
提供的工具类库,包含值是否为空、是否是数字、视频、音频、ppt、邮箱、手机号等。