前言
本文是基于官方最新稳定版本get: ^4.3.8来进行开发
本系列课程将会以最简单的方式来进行讲解,对于零基础也可以轻松掌握,全文深入浅出,每一个章节都会有对于案例来展示效果以及如何运用。
整一个课程系列都是极简的,如果你愿意花两个小时来学习,那么你将很容易掌握GetX并且用GetX应用到企业项目中。
学完本系列课程你将学会:
-
知道什么是GetX
-
会使用Snackbar
-
会使用Dialog
-
会使用BottomSheet
-
会用Navigation
-
会用Obx响应式状态管理
-
会使用GetXController(三种使用方式GetBuilder、事件监听、生命周期、UniqueID)
-
语言国际化配置
-
依赖注入
-
GetX Service
-
GetX Binding(绑定)
-
GetX获取API接口数据并显示
-
获取存储和邮件验证
-
GetView和GetWidget
-
Get Cli 脚手架使用以及常用命令
-
GetX 中使用 GetConnect 和 StateMixin 获取 API 数据
为什么讲解此系列课程?
目前我在市面上找不到一个好的对GetX全面的教程,如果纯看官方文档去自行理解,学习周期长。而视频方面要么就是篇幅太长,学习成本高。要么就是比较零散,学起来像一只无头的苍蝇。所以我干脆直接自己出一个课程,该课程系列从简至深,方便大家系统的对GetX的认识。虽然讲解该系列课程耗费了我大量的时间,但是只要对你有帮助并且能够从中受益,这样就很好。
什么是GetX ?
- GetX 是 Flutter 上的一个轻量且强大的解决方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。
- GetX 有3个基本原则:
- 性能: GetX 专注于性能和最小资源消耗。GetX 打包后的apk占用大小和运行时的内存占用与其他状态管理插件不相上下。
- 效率: GetX 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长。
- 结构: GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护。
为什么使用GetX?
我们知道状态管理的框架有很多,使用原生的相对复杂,都是用ChangeNotifier来更新Widget,如果对于业务逻辑比较复杂还使用这种方式无疑是致命的。
其他的状态管理器也不错,但有其细微的差别。
- BLoC非常安全和高效,但是对于初学者来说非常复杂,这使得人们无法使用Flutter进行开发。
- MobX比BLoC更容易,而且是响应式的,几乎是完美的,但是你需要使用一个代码生成器,对于大型应用来说,这降低了生产力,因为你需要喝很多咖啡,直到你的代码在
flutter clean之后再次准备好(这不是MobX的错,而是codegen真的很慢!)。- Provider使用InheritedWidget来传递相同的监听器,以此来解决上面报告的ChangeNotifier的问题,这意味着对其ChangeNotifier类的任何访问都必须在widget树内。
GetX响应式状态管理器
响应式编程可能会让很多人感到陌生,因为它很复杂,但是GetX将响应式编程变得非常简单。使用 Get 的响应式编程就像使用 setState 一样简单。
- 你不需要创建StreamControllers.
- 你不需要为每个变量创建一个StreamBuilder。
- 你不需要为每个状态创建一个类。
- 你不需要为一个初始值创建一个get。
安装
将 GetX 添加到你的 pubspec.yaml 文件中。
dependencies:
get: ^4.3.8
在需要用到的文件中导入,它将被使用。
import 'package:get/get.dart';
Snackbar介绍
如果想在应用程序中触发某些特定的事件后,需要弹出一则快捷消息,那么使用Snackbar则是最佳的选择,接下来我们看一下GetX如何来联调Snackbar来使用。
Snackbar基本使用
第一步:应用程序入口设置
当我们导入依赖后,在应用程序顶层把GetMaterialApp 作为顶层,如下所示
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(title: Text("GetX Title"),),
),
);
}
}
第二步:调用snackbar
我们可以通过Get.snackbar() 来显示 snackbar ,如下所示
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: Text("GetX Title"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Get.snackbar("Snackbar 标题", "欢迎使用Snackbar");
},
child: Text("显示 Snackbar"))
],
),
),
),
);
}
}
效果展示
如果您运行了代码,那么恭喜你,你已经会用GetX 来展示snackbar 了。你将得到下面的结果:
Dialog介绍
Dialog 底层其实是对AlertDialog进行了封装, 一般用于二次确认的弹出框,比如当点击某个按钮提交资料时,需要用户二次确认,以防止误操作。
Dialog使用
第一步:应用程序入口设置
当我们导入依赖后,在应用程序顶层把GetMaterialApp 作为顶层,如下所示
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/DialogExample/DialogExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: DialogExample(),
);
}
}
第二步:调用Dialog
我们可以通过Get.defaultDialog() 来显示 dialog ,如下所示
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class DialogExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Title"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Get.defaultDialog();
},
child: Text("显示 Dialog"))
],
),
),
);
}
}
效果展示
如果您运行了代码,那么恭喜你,你已经会用GetX 来展示dialog 了。你将得到下面的结果:
BottomSheet介绍
BottomSheet 是底部弹出的一个组件,常用于单选、验证码二次校验弹窗等,GetX的BottomSheet底部弹出是自定义通过路由push的方法实现底部弹窗的一个效果。
BottomSheet使用
我们可以通过GetX很轻松的调用bottomSheet(),而且无需传入context,下面我给出一个例子,使用GetX弹出bottomSheet并很轻松的实现切换主题
第一步:应用程序入口设置
当我们导入依赖后,在应用程序顶层把GetMaterialApp 作为顶层,如下所示
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/DialogExample/DialogExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: DialogExample(),
);
}
第二步:调用BottomSheet
我们可以通过Get.bottomSheet() 来显示 BottomSheet ,如下所示
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class BottomSheetExample extends StatelessWidget {
GlobalKey<NavigatorState> _navKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Title"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(onPressed: () {
Get.bottomSheet(
Container(
child: Wrap(
children: [
ListTile(
leading: Icon(Icons.wb_sunny_outlined),
title: Text("白天模式"),
onTap: () {
Get.changeTheme(ThemeData.light());
},
),
ListTile(
leading: Icon(Icons.wb_sunny),
title: Text("黑夜模式"),
onTap: () {
Get.changeTheme(ThemeData.dark());
},
)
],
),
)
);
}, child: Text("Bottom Sheet"))
],
),
),
);
}
}
效果展示
如果您运行了代码,那么恭喜你,你已经会用GetX 来展示BottomSheet 了。你将得到下面的结果:
Navigation路由跳转
使用GetX 进行路由跳转非常的简单,只需要调用Get.to()即可进行路由跳转,而系统的路由跳转需要写八行代码,这是不能忍受的事情,而且涉及到跳转动画设置 、动画时长定义、动画曲线 等设置那就更加的复杂,而GetX为我们封装了Navigation,无需context可进行跳转,并且能很方便的使用跳转动画等。
Navigation---通过to方法进行路由跳转
第一步:应用程序入口设置
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/NavigationForNamedExample/NavigationForNamedExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: NavigationForNamedExample(),
);
}
}
第二步:调用to方法
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/NavigationExample/home.dart';
import 'package:get/get.dart';
class NavigationExample extends StatelessWidget {
GlobalKey<NavigatorState> _navKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Navigation"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
Get.to(Home());
},
child: Text("跳转到首页"))
],
),
),
);
}
}
效果展示
Navigation---通过toNamed进行路由跳转
第一步:应用程序入口设置
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/NavigationForNamedExample/NavigationForNamedExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
initialRoute: "/",
defaultTransition: Transition.zoom,
getPages: [
GetPage(name: "/", page: () => MyApp()),
GetPage(name: "/home", page: () => Home()),
GetPage(name: "/my", page: () => My(), transition: Transition.rightToLeft)
],
home: NavigationForNamedExample(),
);
}
}
第二步:调用toNamed
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NavigationForNamedExample extends StatelessWidget {
GlobalKey<NavigatorState> _navKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX NavigationForNamed"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
Get.toNamed("/my");
},
child: Text("跳转到首页"))
],
),
),
);
}
}
效果展示
Obx响应式状态管理
介绍
响应式编程可能会让很多人感到陌生,因为它很复杂,但是GetX将响应式编程变得非常简单。
- 你不需要创建StreamControllers.
- 你不需要为每个变量创建一个StreamBuilder。
- 你不需要为每个状态创建一个类。
- 你不需要为一个初始值创建一个get。
使用 Get 的响应式编程就像使用 setState 一样简单。
定义Obx变量的三种方式
// 第一种 使用 Rx{Type}
// final name = RxString('');
// final isLogged = RxBool(false);
// final count = RxInt(0);
// final balance = RxDouble(0.0);
// final items = RxList<String>([]);
// final myMap = RxMap<String, int>({});
// 第二种是使用 Rx,规定泛型 Rx<Type>。
// final name = Rx<String>('');
// final isLogged = Rx<Bool>(false);
// final count = Rx<Int>(0);
// final balance = Rx<Double>(0.0);
// final number = Rx<Num>(0)
// final items = Rx<List<String>>([]);
// final myMap = Rx<Map<String, int>>({});
// 自定义类 - 可以是任何类
// final user = Rx<User>();
// 第三种更实用、更简单、更可取的方法,只需添加 .obs 作为value的属性。
// final name = ''.obs;
// final isLogged = false.obs;
// final count = 0.obs;
// final balance = 0.0.obs;
// final number = 0.obs;
// final items = <String>[].obs;
// final myMap = <String, int>{}.obs;
// 自定义类 - 可以是任何类
// final user = User().obs;
计数器案例
第一步:应用程序入口设置
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/ObxCountExample/ObxCountExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: ObxCountExample(),
);
}
}
第二步:声明Rx变量以及改变计数器的方法
RxInt count = RxInt(0);
// var count = Rx<double>(0);
// var count = 0.obs;
void increment() {
count++;
}
第三步:使用Obx监听值的改变
Obx(() => Text(
"count的值为: $count",
style: TextStyle(color: Colors.red, fontSize: 30),
)),
完整代码
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ObxCountExample extends StatelessWidget {
RxInt count = RxInt(0);
// var count = Rx<double>(0);
// var count = 0.obs;
void increment() {
count++;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Obx---计数器"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Obx(() => Text(
"count的值为: $count",
style: TextStyle(color: Colors.red, fontSize: 30),
)),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
increment();
},
child: Text("点我加1"))
],
),
),
);
}
}
效果展示
自定义类案例
第一步:应用程序入口设置
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/ObxCustomClassExample/ObxCustomClassExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: ObxCustomClassExample(),
);
}
}
第二步:创建Teacher类
import 'package:get/get.dart';
class Teacher {
// rx 变量
var name = "Jimi".obs;
var age = 18.obs;
// 构造函数创建
// var name;
// var age;
// Teacher({this.name, this.age});
}
第三步:监听Teacher状态改变
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/ObxCustomClassExample/Teacher.dart';
import 'package:get/get.dart';
class ObxCustomClassExample extends StatelessWidget {
var teacher = Teacher();
// final teacher = Teacher(name: "Jimi", age: 18).obs;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Obx---自定义类"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Obx(() => Text(
"我的名字是 ${teacher.name.value}",
style: TextStyle(color: Colors.red, fontSize: 30),
)),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
teacher.name.value = teacher.name.value.toUpperCase();
// teacher.update((val) {
// teacher.value.name = teacher.value.name.toString().toUpperCase();
// });
},
child: Text("转换为大写"))
],
),
),
);
}
}
效果展示
总结
通过这个章节知道了GetX是一个高性能的状态管理、智能的依赖注入和便捷的路由管理,我们介绍了什么GetX以及如果使用,包括Snackbar、Dialog、BottomSheet、Navigation、Obx 等进行了一个简单的介绍,使用GetX后能极简的缩减我们的代码。