什么是Getx?

Getx 是Flutter一个轻量且强大的插件扩展,提供了高性能的状态管理、智能的依赖注入和便捷的路由管理。

Getx有3个基本原则

性能: GetX 专注于性能和最小资源消耗。打包后的apk占用大小和运行时的内存占用与其他状态管理插件不相上下。

效率: GetX 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长。

结构: GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护。

为什么使用Getx?

GetX响应式状态管理器

响应式编程可能会让很多人感到陌生,因为它很复杂,但是GetX将响应式编程变得非常简单。使用 Get 的响应式编程就像使用 setState 一样简单。

  • 无需创建StreamControllers.
  • 无需为每个变量创建一个StreamBuilder。
  • 无需为每个状态创建一个类。
  • 无需为一个初始值创建一个get。

安装

命令

flutter pub add get

依赖

ps: 具体版本参考:get | Flutter Package (pub.dev)

dependencies:
  get: ^4.6.5

Get的使用

应用程序入口设置

当我们导入依赖后,在应用程序顶层把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"),),
      ),
    );
  }
}

get的小试牛刀:snackbar

通过Get.snackbar() 来显示 snackbar ,如下所示

Get.snackbar("Snackbar 标题", "欢迎使用Snackbar");

Dialog

Dialog 底层其实是对AlertDialog进行了封装, 一般用于二次确认的弹出框,比如当点击某个按钮提交资料时,需要用户二次确认,以防止误操作。

Get.defaultDialog();

Dialog属性和说明

字段属性描述
titleString弹出的标题,默认(Alert)
titlePaddingEdgeInsetsGeometry标题的内边距,默认(EdgeInsets.all(8))
titleStyleTextStyle标题的样式
middleTextString中间内容区域显示的文字
middleTextStyleTextStyle中间内容区域显示的文字样式
contentWidget弹出的内容,该值设置后middleText将无效
contentPaddingEdgeInsetsGeometry内容的内边距,默认(EdgeInsets.all(8))
onConfirmVoidCallback确认按钮回调
onCancelVoidCallback取消按钮回调
onCustomVoidCallback自定义按钮回调
cancelTextColorColor取消按钮文字的颜色
confirmTextColorColor确认按钮文字的颜色
textConfirmString确认按钮的文字
textCancelString取消按钮的文字
textCustomString自定义按钮的文字
confirmWidget确认按钮的组件
cancelWidget取消按钮的组件
customWidget自定义按钮的组件
backgroundColorColor弹出框的背景颜色
barrierDismissiblebool是否可以通过点击背景关闭弹窗
buttonColorColor按钮的文字颜色,根据按钮类型来设定不同的位置
radiusdouble弹出框的圆角大小,默认20
actionsList增加额外的子组件
onWillPopWillPopCallback拦截关闭之前做一些操作
navigatorKeyGlobalKey用于打开对话框的key

BottomSheet介绍

BottomSheet 是底部弹出的一个组件,常用于单选、验证码二次校验弹窗等,GetXBottomSheet底部弹出是自定义通过路由push的方法实现底部弹窗的一个效果。

BottomSheet使用

我们可以通过GetX很轻松的调用bottomSheet(),而且无需传入context,下面我给出一个例子,使用GetX弹出bottomSheet并很轻松的实现切换主题

我们可以通过Get.bottomSheet() 来显示 BottomSheet ,如下所示

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());
            },
          )
        ],
      ),
    ));

BottomSheet属性和说明

字段属性描述
bottomsheetWidget弹出的Widget组件
backgroundColorColorbottomsheet的背景颜色
elevationdoublebottomsheet的阴影
persistentbool是否添加到路由中
shapeShapeBorder边框形状,一般用于圆角效果
clipBehaviorClip裁剪的方式
barrierColorColor弹出层的背景颜色
ignoreSafeAreabool是否忽略安全适配
isScrollControlledbool是否支持全屏弹出,默认false
useRootNavigatorbool是否使用根导航
isDismissiblebool点击背景是否可关闭,默认ture
enableDragbool是否可以拖动关闭,默认true
settingsRouteSettings路由设置
enterBottomSheetDurationDurationbottomsheet进入时的动画时间
exitBottomSheetDurationDurationbottomsheet退出时的动画时间

使用GetX 进行路由跳转非常的简单,只需要调用Get.to()即可进行路由跳转,而系统的路由跳转需要写八行代码,这是不能忍受的事情,而且涉及到跳转动画设置 、动画时长定义动画曲线 等设置那就更加的复杂,而GetX为我们封装了Navigation,无需context可进行跳转,并且能很方便的使用跳转动画等。

Get.to(Home());

通过toNamed进行路由跳转

要使用toNamed需要先进行路由的名称配置

第一步:应用程序入口设置

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(),
    );
  }
}

第二步:使用

Get.toNamed("/my");

Obx响应式状态管理

定义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;

使用

声明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("Obx"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Obx(() => Text(
              "count的值为: $count",
              style: TextStyle(color: Colors.red, fontSize: 20),
            )),
            SizedBox(height: 10,),
            ElevatedButton(
              onPressed: () {
                increment();
              },
              child: Text("点我增加"))
          ],
        ),
      ),
    );
  }
}

GeorgieのBlog,分享生活的点点滴滴,分享代码干货