Flutter GetX的简单使用

发布时间 2023-11-06 17:14:28作者: 桃李子

1、pubspec.yaml添加get依赖,再更新项目包依赖

dependencies:
  get: ^4.6.5

2、更改main文件如下:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_application_1/route/pageRoute.dart'; // 路由相关,配置见第3点
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, appBarTheme: const AppBarTheme( centerTitle: true, )), debugShowCheckedModeBanner: true, initialRoute: "/", defaultTransition: Transition.rightToLeftWithFade, getPages: AppPage.routes, ); } }

3、修改路由文件如下:

import 'package:flutter_application_1/pages/myTest.dart';
import 'package:flutter_application_1/pages/newPage.dart';
import 'package:get/get.dart';

class AppPage {
  static final routes = [
    GetPage(name: "/", page: () => const MyTest()),
    GetPage(
      name: "/test",
      page: () => const MyTest(),
      // middlewares: const [] // 中间件
    ),
    GetPage(
        name: "/new",
        page: () => const NewPage(),
        transition: Transition.leftToRightWithFade),
  ];
}

4、路由跳转方式:

Get.toNamed("/new");
或
Get.to(NewPage());

Get.back(); // 返回上一个路由、关闭弹窗、弹出层等

Get.offAll(); // 返回根

Get.off(XXX); // 进入下个页面,下个页面没有返回

// ......

5、状态管理(当前页面)

// 定义赋初值
RxInt _anum = 0.obs;
RxString _astr = ''.obs;

// 修改值
_anum.value++;
_astr.value = 'abcdefg';

// 动态渲染值
Obx(() => Text('${_anum.value} ${_astr.value}'));

 6、状态管理控制器(多页面共享数据)

  新增控制器文件如下:

import 'package:get/get.dart';

class CounterController extends GetxController {
  RxInt counter = 0.obs;

  // 以下为周期函数 @override
void onInit() { print('onInit'); super.onInit(); } @override void onClose() { // 控制器绑定在路由上的话,路由销毁则触发 print('onClose'); super.onClose(); } @override void onReady() { print('onReady'); super.onReady(); } void inc() { counter.value++; update(); // 调用obx更新数据,不然数据不会更新 } void dec() { counter.value--; update(); } }

  页面一:

// 实例化控制器,用put,lazyPut
CounterController counterController = Get.put(CounterController());

// 使用
Obx(() => Text('${counterController.counter}')),
ElevatedButton(
  onPressed: () {
    counterController.inc();
  },
  child: XXX
),

  页面二:

// 获取控制器实例,用find
final CounterController counterController = Get.find();

// 使用方式同页面一

**:这里需要注意一个问题,这样的写法需要先实例化控制器,才可以使用find去获取控制器实例,如果在未实例化之前打开了页面二,则获取控制器实例这里会报错。

7、创建全局控制器绑定(可解决控制器未实例化获取实例的问题)

  新建binding.dart文件如下:

import 'package:flutter_application_1/controller/counter.dart';
import 'package:get/get.dart';

// 全局
class AllControllerBinding implements Bindings {
  @override
  void dependencies() {
    Get.lazyPut<CounterController>(() => CounterController()); // 实现控制器的懒实例化
  }
}

  在main文件GetMaterialApp中添加如下行(引入binding文件):

initialBinding: AllControllerBinding(), // 全局绑定GetxController

  页面一、二实例化与获取实例的方式改为如下:

CounterController counterController = Get.find();

8、当个页面的控制器绑定

  新建一个counterBinding.dart文件如下:

import 'package:flutter_application_1/controller/counter.dart';
import 'package:get/get.dart';

// 全局
class ViewControllerBinding implements Bindings {
  @override
  void dependencies() {
    Get.lazyPut<CounterController>(() => CounterController());
  }
}

  找到需要使用这个控制器的页面路由,修改如下:

GetPage(
  name: "/view",
  page: () => const ViewTest(),
  transition: Transition.leftToRightWithFade,
  binding: ViewControllerBinding()
)

  页面继承如下方式:

class ViewTest extends GetView<CounterController> {
  ......    
 Obx(() => Text('${controller.counter}')),
    ElevatedButton(
      onPressed: () {
        controller.inc();
      },
      child: XXX
    ),
}

9、Get提供的工具类:GetUtils

GetUtils.isEmail('xxx')
GetUtils.isPhoneNumber('xxx')
GetUtils.isImage('xxx')
......

看Get源码,有更多其他的方法

10、Get的一些高级API

// 给出当前页面的args。
Get.arguments

//给出以前的路由名称
Get.previousRoute

// 给出要访问的原始路由,例如,rawRoute.isFirst()
Get.rawRoute

// 允许从GetObserver访问Rounting API。
Get.routing

// 检查 snackbar 是否打开
Get.isSnackbarOpen

// 检查 dialog 是否打开
Get.isDialogOpen

// 检查 bottomsheet 是否打开
Get.isBottomSheetOpen

// 删除一个路由。
Get.removeRoute()

//反复返回,直到表达式返回真。
Get.until()

// 转到下一条路由,并删除所有之前的路由,直到表达式返回true。
Get.offUntil()

// 转到下一个命名的路由,并删除所有之前的路由,直到表达式返回true。
Get.offNamedUntil()

//检查应用程序在哪个平台上运行。
GetPlatform.isAndroid
GetPlatform.isIOS
GetPlatform.isMacOS
GetPlatform.isWindows
GetPlatform.isLinux
GetPlatform.isFuchsia

//检查设备类型
GetPlatform.isMobile
GetPlatform.isDesktop

//所有平台都是独立支持web的!
//你可以知道你是否在浏览器内运行。
//在Windows、iOS、OSX、Android等系统上。
GetPlatform.isWeb

// 相当于.MediaQuery.of(context).size.height,
//但不可改变。
Get.height
Get.width

// 提供当前上下文。
Get.context

// 在你的代码中的任何地方,在前台提供 snackbar/dialog/bottomsheet 的上下文。
Get.contextOverlay

// 注意:以下方法是对上下文的扩展。
// 因为在你的UI的任何地方都可以访问上下文,你可以在UI代码的任何地方使用它。
// 如果你需要一个可改变的高度/宽度(如桌面或浏览器窗口可以缩放),你将需要使用上下文。
context.width
context.height

// 让您可以定义一半的页面、三分之一的页面等。
// 对响应式应用很有用。
// 参数: dividedBy (double) 可选 - 默认值:1
// 参数: reducedBy (double) 可选 - 默认值:0。
context.heightTransformer()
context.widthTransformer()

/// 类似于 MediaQuery.of(context).size。
context.mediaQuerySize()

/// 类似于 MediaQuery.of(context).padding。
context.mediaQueryPadding()

/// 类似于 MediaQuery.of(context).viewPadding。
context.mediaQueryViewPadding()

/// 类似于 MediaQuery.of(context).viewInsets。
context.mediaQueryViewInsets()

/// 类似于 MediaQuery.of(context).orientation;
context.orientation()

///检查设备是否处于横向模式
context.isLandscape()

///检查设备是否处于纵向模式。
context.isPortrait()

///类似于MediaQuery.of(context).devicePixelRatio。
context.devicePixelRatio()

///类似于MediaQuery.of(context).textScaleFactor。
context.textScaleFactor()

///查询设备最短边。
context.mediaQueryShortestSide()

///如果宽度大于800,则为真。
context.showNavbar()

///如果最短边小于600p,则为真。
context.isPhone()

///如果最短边大于600p,则为真。
context.isSmallTablet()

///如果最短边大于720p,则为真。
context.isLargeTablet()

///如果当前设备是平板电脑,则为真
context.isTablet()