https://www.bilibili.com/video/BV17m4y1a7zJ/?spm_id_from=333.337.search-card.all.click&vd_source=2c2d0ce64b817501491ef975f77fea05 pub地址:https://pub.dev/packages/get 官方文档:https://gitcode.net/mirrors/jonataslaw/getx/-/blob/master/README.zh-cn.md
初始化
引入依赖
dependencies:
flutter:
sdk: flutter
sqflite: ^2.0.0
get: ^4.0.0
修改MaterialApp
import 'package:get/get.dart';
main() {
runApp(GetMaterialApp(
home: MyGetX(),
));
}
状态管理
状态可以简单的理解为用户界面上可变的值,这些值一般会随用户行为变化,如何将这些值和用户的交互绑定,从而实时更新在用户界面上,称为状态管理。GetX提供了响应式变量和状态控制器实现状态管理
响应式变量
普通变量的局限性
在无状态部件中如果想实现响应变量那是很麻烦的,就拿经典的例子,点击按钮更新Text上的文本实现计数器的功能。 使用StatefulWidget
中的setState()
实现状态变量times
更新。 但使用StatelessWidget
没有管理状态的实现,无法实现对状态的响应监听,例如如下实现,点击按钮,文本上的数字并不会变化。
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(
home: MyGetX(),
));
}
class MyGetX extends StatelessWidget {
@override
Widget build(BuildContext context) {
var times = 0;
return Scaffold(
appBar: AppBar(
title: Text('getx响应变量'),
),
body: Center(
child: Text(
times.toString(),
style: TextStyle(fontSize: 20),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
times++;
},
child: Icon(Icons.add),
),
);
}
}
定义响应式变量
使用GetX定义响应变式量,对变量用后缀** .obs**
修饰即可。如:这时的times就是一个响应式变量了
var times=0.obs;
获取响应式变量
通过对象属性取值的形式拿出对应的值
int timesValue=times.value;
绑定响应式变量
在界面上使用响应式变量只需在使用变量的控件上包裹 Obx
即可实现响应式更新,即变量的值发生变化时自动刷新界面:
child: Obx(
() => Text(
"${times.value}",
style: TextStyle(fontSize: 20),
),
),
响应式变量实现计数器
这样在无状态变量中也能实现计数器状态的管理,用户点击按钮,Text部件上的数字会实时增加。
import 'package:flutter/material.dart';
import 'package:get/get.dart';
main() {
runApp(GetMaterialApp(
home: MyGetX(),
));
}
class MyGetX extends StatelessWidget {
@override
Widget build(BuildContext context) {
var times = 0.obs;
return Scaffold(
appBar: AppBar(
title: Text('getx响应变量'),
),
body: Center(
child: Obx(
() => Text(
"${times.value}",
style: TextStyle(fontSize: 20),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
times++;
},
child: Icon(Icons.add),
),
);
}
}
状态管理器
定义状态管理器
GetX 还提供了使用 Controller 来管理状态,实现一个自定义 Controller 类继承自 GetxController ,Controller 中进行业务逻辑的处理,当需要改变状态数据时调用 update() 来通知数据改变。
class TimesController extends GetxController{
int times=0;
void addTimes(){
times++;
update();
}
}
绑定状态管理器
在界面中使用时需要使用 GetBuilder 进行包裹,这样使用 Controller 中的数据变化时,调用 update() 后就会刷新界面控件。
//状态管理器
GetBuilder<TimesController>(
//第一次使用需要初始化
init: TimesController(),
builder: (controller) {
return Text(
"状态管理器:${controller.times}",
style: TextStyle(fontSize: 20),
);
}),
第一次使用GetController时需要使用init初始化,之后再使用的地方就不需要初始化了。
获取状态管理器
获取到controller的实例可以通过Get.find()方法,通过实例对象调用其中的业务函数。
//状态管理器
TimesController controller=Get.find();
controller.addTimes();
状态管理器实现计数器
import 'package:flutter/material.dart';
import 'package:get/get.dart';
main() {
runApp(GetMaterialApp(
home: MyGetX(),
));
}
class MyGetX extends StatelessWidget {
@override
Widget build(BuildContext context) {
var times = 0.obs;
return Scaffold(
appBar: AppBar(
title: Text('getx响应变量'),
),
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
//响应式变量
Obx(
() => Text(
"响应式变量:${times.value}",
style: TextStyle(fontSize: 20),
),
),
//状态管理器
GetBuilder<TimesController>(
//第一次使用需要初始化
init: TimesController(),
builder: (controller) {
return Text(
"状态管理器:${controller.times}",
style: TextStyle(fontSize: 20),
);
}),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//响应式变量
times++;
//状态管理器
TimesController controller=Get.find();
controller.addTimes();
},
child: Icon(Icons.add),
),
);
}
}
class TimesController extends GetxController {
int times = 0;
void addTimes() {
times++;
update();
}
}
路由管理
Flutter中页面的跳转就是通过路由实现的。GetX提供了普通路由和别名路由
普通路由
使用Flutter原生支持的路由跳转,我们一般会这么写,下面代码中的GetXRouter()是我定义的一个新界面:
Navigator.push(
context, MaterialPageRoute(builder: (_) => GetXRouter()));
}
使用GetX普通路由大大的简化了我们的代码,言简意赅。
Get.to(GetXRouter());
如果需要传递参数到下一个界面,可以使用arguments
,它可以传递任何类型的参数,通过我们会用一个dynamic
获取这个参数。
dynamic tags=Get.arguments;
除了Get.to(),常用的路由跳转的方法还有:
- Get.to():导航到新的界面
- Get.back():返回到上一个界面
- Get.offAll():进入下一个界面并取消之前的所有路由
- Get.off():进入下一个界面,但没有导航到上一个界面的选项;例如闪屏页进入登录页
别名路由
别名路由顾名思义就是为每一个界面定义一个别名,通过别名指定跳转的路由。
定义路由管理类
定义一个RouteGet
类来统一管理路由名和界面的映射关系。主要是借助GetX中的GetPage
这个类来声明这种映射关系
import 'package:demo2/get_study/getx.dart';
import 'package:demo2/get_study/getx_router.dart';
import 'package:get/get.dart';
class RouteGet {
//page name
static const String main = '/main';
static const String route = '/route';
//page map
static final List<GetPage> getPages = [
GetPage(
name: main,
page: () => MyGetX(),
),
GetPage(
name: route,
page: () => GetXRouter(),
),
];
}
初始化路由
定义好路由管理类之后,需要在App中初始化,在GetMaterialApp中,进行initialRoute
和 getPages
的配置,即初始页面和路由映射集合:
main() {
runApp(GetMaterialApp(
// home: MyGetX(),
initialRoute: RouteGet.main,
getPages: RouteGet.getPages,
));
}
别名路由的使用
使用别名路由,和普通路由的方法差别就是在其后多了Named
,例如:
- Get.toNamed()
- Get.offNamed()
- 等等
如下可以实现跳转到GetXRouter()
界面,并传递参数的功能
Get.toNamed(RouteGet.route, arguments: 'Get.to别名路由');
跳转动画
在界面间路由可以指定特定的转场动画,通过transition
属性设置转场动画 普通路由直接在Get.to()中指定:
Get.to(GetXRouter(),
transition: Transition.rightToLeft,
duration: Duration(seconds: 2),
arguments: 'GetX普通路由');
对于命名路由需要在定义映射关系时指定:
GetPage(
name: beautify,
page: () => GetBeautify(),
transition: Transition.zoom,
transitionDuration: Duration(seconds: 2),
),
路由中间件
路由中间件的学习:https://juejin.cn/post/7129137885063675935 什么是路由中间件呢? 例如在用户打开APP的时候一般会判断是否有登录缓存,如何有登录缓存就直接进入APP主页,否则会路由到登录页。这中间的逻辑判断条件就可以在路由中间件执行。 首先需要继承GetMiddleware
负责实现中间件的类,并重写其中的方法redirect()
当被调用路由的页面被搜索时,这个函数将被调用。它将RouteSettings
作为重定向的结果。或者给它返回null,就没有重定向了。 返回值就是重定向的页面,例如我将此中间件配置在前往GetBeautify
页的路由映射中,但是中间件最终重定向到GetXRouter
页,因此我们可以通过这个函数来根据判断结果,决定路由到的页面。
import 'package:demo2/get_study/RouteGet.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class Middle extends GetMiddleware {
@override
RouteSettings? redirect(String? route) {
print('来自中间件的消息');
return RouteSettings(name: RouteGet.route);
}
}
并在在自定义的配置命名路由的类中绑定路由中间件,这样在路由到这个页面之前会先调用中间件Middle
GetPage(
name: beautify,
page: () => GetBeautify(),
transition: Transition.zoom,
transitionDuration: Duration(seconds: 2),
middlewares: [
Middle(),
],
),