Flutter 应用程序中的 GetX 包入门
已发表: 2022-03-10Flutter 是构建真正跨平台的原生应用程序的最快方式之一。 它提供的功能允许开发人员为其用户构建真正漂亮的 UI 体验。
然而,大多数时候要实现导航到屏幕、状态管理和显示警报等功能,需要大量样板文件。 这些样板往往会降低开发人员试图构建功能并满足他们的最后期限的开发效率。
以在 Flutter 应用程序中导航到屏幕所需的样板为例。 假设您要导航到名为AboutScreen
的屏幕。 你必须写:
Navigator.push( context, MaterialPageRoute(builder: (context) => AboutScreen()), );
执行以下操作会更高效且对开发人员友好:
Get.to(AboutScreen());
当您需要导航回 Flutter 中的上一页时,您必须编写:
Navigator.pop(context);
您会注意到,我们总是依赖于上下文属性来处理像在屏幕之间导航这样常见的事情。 如果相反,我们可以这样做:
Get.back();
上面的例子是一些可以改进 Flutter 应用程序开发的方法,使其更直观、更高效、更少样板。 如果你喜欢简单并且高效地构建功能和想法,那么在 Flutter 中,Get 包会让你感兴趣。
什么是 GetX
Get 或 GetX 是一个快速、稳定、超轻量级的框架,用于构建 Flutter 应用程序。
GetX 以简单实用的方式提供开箱即用的高性能状态管理、智能依赖注入和路由管理。
GetX 旨在最大限度地减少样板文件,同时还为开发人员在构建应用程序时提供简单直观的语法。 GetX 的核心是以下三个原则:
- 表现
GetX 通过实现其功能以消耗尽可能少的资源来关注应用程序的性能。 - 生产率
GetX 希望开发人员使用其功能尽快提高工作效率。 它通过采用易于记忆的语法和实践来做到这一点。 例如,一般来说,开发人员应该关注从内存中删除控制器,但 GetX 开箱即用提供了智能管理,可以监视应用程序中的控制器,并在默认情况下不使用它们时将其删除。 - 组织
GetX 允许在 Flutter 应用程序中解耦视图、表示逻辑、业务逻辑、依赖注入和导航。 您不需要上下文在路线之间导航,因此您不依赖小部件树进行导航。 您不需要上下文来通过inheritedWidget
的Widget 访问您的控制器/块,因此您可以将您的表示逻辑和业务逻辑与您的视图层完全分离。 您不需要通过 multiproviders 将 Controllers/Models/Blocs 类注入到您的小部件树中,因为此 GetX 使用其自己的依赖注入功能,将 DI 与其视图完全解耦。
GetX 的特点
GetX 附带了一些您在 Flutter 中进行日常应用开发所需的功能。 让我们看看它们:
状态管理
GetX 的旗舰功能之一是其直观的状态管理功能。 GetX 中的状态管理可以用很少或没有样板来实现。
路线管理
GetX 提供用于在 Flutter 应用程序中导航的 API。 这个 API 很简单,需要的代码更少。
依赖管理
GetX 提供了一种智能方式来管理 Flutter 应用程序中的依赖项,例如视图控制器。 GetX 将从内存中删除任何当前未使用的控制器。 这是您作为开发人员必须手动完成的任务,但 GetX 会自动为您自动完成。
国际化
GetX 提供开箱即用的 i18n,允许您编写具有各种语言支持的应用程序。
验证
GetX 提供了在 Flutter 应用程序中执行输入验证的验证方法。 这非常方便,因为您不需要安装单独的验证包。
贮存
GetX 在内存中提供了一个快速、轻量且同步的键值对,它在每次操作时将数据备份到磁盘。 它完全用 Dart 编写,很容易与核心 GetX 包集成。
GetX 入门
现在您已经了解了 GetX 是什么以及它提供的功能和优势,让我们看看如何在您的应用程序中设置它。 我们将构建一个演示应用程序,以查看我们提到的大部分功能。 让我们开始吧。
创建一个全新的 Flutter 应用程序
我们将从通过 Flutter CLI 创建一个全新的 Flutter 应用程序开始。 我假设您的机器已经设置好使用 Flutter 进行应用程序开发。 所以我们运行:
flutter create getx_demo
这将生成 Flutter 应用程序所需的基本代码。 接下来,在您选择的编辑器中打开您刚刚创建的项目(我们将在本文中使用 VS Code)。 然后我们将运行该项目以确保它工作正常(确保您连接了设备或正在运行仿真器/模拟器)。
当应用程序运行时,您将看到 Flutter 在创建新的 Flutter 应用程序时为您搭建的默认计数器应用程序。 我们要做的是实现完全相同的计数器应用程序,但使用 GetX 来管理应用程序的状态(即计数变量)。
我们将从清除main.dart
开始,只留下这段代码:
# main.dart import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
到现在为止,我们的应用程序已经被破坏了,因为没有MyHomePage
小部件了。 让我们解决这个问题。 使用 GetX,我们不需要有状态的小部件,而且我们的 UI 可以清楚地与我们的业务逻辑分离。 所以我们将在lib/
中创建两个目录。 这些目录是:
views/ | 在我们的应用程序中保存屏幕。 |
controllers/ | 在我们的应用程序中保存所有屏幕的控制器。 |
让我们在views/
中创建MyHomePage
小部件。 该文件的名称将是my_home_page.dart
。 创建它后,将以下代码段添加到其中:
import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { final String title; MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '0', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: null, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
现在我们有了MyHomePage
小部件,让我们在main.dart
中导入它。 在import 'package:flutter/material.dart';
import './views/my_home_page.dart';
现在您的main.dart
文件应如下所示:
import 'package:flutter/material.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
现在保存应用程序时,所有错误都应该已修复,应用程序将运行。 但是您会注意到,当您再次单击该按钮时,计数器不会更新。 如果您查看views/my_home_page.dart
代码,您会看到我们只是将0
硬编码为 Text 小部件的值,并将null
传递给按钮的onPressed
处理程序。 让我们将 GetX 加入其中,让应用程序再次发挥作用。
安装 GetX
前往 pub.dev 上的 GetX 安装页面,您将看到要复制到pubspec.yml
文件中以安装 GetX 的代码行。 截至撰写本文时,GetX 的当前版本为 3.23.1。 所以我们将复制以下行:
get: ^3.23.1
然后将其粘贴到我们的pubspec.yml
文件的dependencies
项部分下。 保存文件时,应该会自动为您安装 get。 或者您可以在终端中手动运行。
flutter pub get
pubspec.yml
文件的依赖项部分应如下所示:
dependencies: flutter: sdk: flutter get: ^3.23.1
GetxController
我们已经提到 GetX 允许您将应用程序的 UI 与逻辑分离。 它通过提供一个GetxController
类来实现这一点,您可以继承该类来为应用程序的视图创建控制器类。 对于我们当前的应用程序,我们有一个视图,因此我们将为该视图创建一个控制器。 前往controllers/
目录并创建一个名为my_home_page_controller.dart
的文件。 这将保存MyHomePage
视图的控制器。
创建文件后,首先通过将以下内容添加到文件顶部来导入 GetX 包:
import 'package:get/get.dart';
然后,您将在其中创建一个名为MyHomePageController
的类并扩展GetxController
类。 这是文件的样子:
import 'package:get/get.dart'; class MyHomePageController extends GetxController {}
让我们将计数状态添加到我们创建的类中。
final count = 0;
在 GetX 中,使变量可观察——这意味着当它发生变化时,依赖于它的应用程序的其他部分将得到通知。 为此,我们只需将.obs
添加到变量初始化中。 因此,对于我们上面的count
变量,我们将.obs
添加到0
。 所以上面的声明现在看起来像这样:
final count = 0.obs;
这是我们的控制器文件现在的样子:
import 'package:get/get.dart'; class MyHomePageController extends GetxController { final count = 0.obs; }
为了用MyHomePageController
,我们将实现increment
方法。 这是执行此操作的代码段:
increment() => count.value++;
您会注意到我们需要将.value
添加到 count 变量以增加它。 我们这样做是因为将.obs
添加到变量使其成为可观察变量,并且要获取可观察变量的值,您可以从value
属性中执行此操作。
这样我们就完成了控制器。 现在,当 count 的值发生变化时,我们应用程序中使用它的任何部分都会自动更新。
我们现在将转到我们的视图并让它知道我们刚刚创建的控制器。 我们将通过使用 GetX 依赖管理功能实例化控制器类来做到这一点。 这将确保我们的控制器在不再需要时不会在内存中。
在views/my_home_page.dart
导入 Get 包以及您创建的控制器,如下所示:
import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart';
然后在MyHomePage
类中,我们将实例化MyHomePageController
:

final MyHomePageController controller = Get.put(MyHomePageController());
现在我们有了MyHomePageController
的一个实例,我们可以使用状态变量以及方法。 因此,从状态开始,在 GetX 中标记 UI 的一部分以在状态变量更改时重新构建,您将使用Obx
小部件包装该部分。 GetX 提供了其他方法来执行此操作,但这种方法更简单、更简洁。
对于我们的计数应用程序,我们希望 Text 小部件使用当前计数进行更新。 因此,我们将使用Obx
小部件包装 Text 小部件,如下所示:
Obx(() => Text('0',style: Theme.of(context).textTheme.headline4,),)
接下来,我们将使用MyHomePageController
中的 count 变量替换静态字符串0
,如下所示:
Obx(() => Text('${controller.count.value}', ,style: Theme.of(context).textTheme.headline4,),)
最后,我们将在按下floatingActionButton
时调用 increment 方法,如下所示:
floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ),
所以总的来说,我们的MyHomePage
视图文件现在应该是这样的:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class MyHomePage extends StatelessWidget { final String title; final MyHomePageController controller = Get.put(MyHomePageController()); MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Obx( () => Text( '${controller.count.value}', style: Theme.of(context).textTheme.headline4, ), ) ], ), ), floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
当您保存应用程序或重新运行它时,计数器应用程序应该像我们第一次创建应用程序时一样工作。
我相信您已经看到 GetX 的状态管理是多么直观,我们不必编写大量样板文件,并且随着您的应用程序变得复杂,这种简单性将更加明显。 您还会注意到我们的视图不持有或维护任何状态,因此它可以是无状态的小部件。 视图的大脑现在是一个控制器类,它将保存视图和方法的状态。
GetX 中的导航
我们已经在 GetX 中看到了状态管理。 现在让我们看看 GetX 如何在您的应用程序中支持导航。 要激活 GetX 的 Navigation 功能,您只需在main.dart
中进行一项更改,即将MaterialApp
小部件转换为GetMaterialApp
小部件。 让我们首先在main.dart
顶部导入 Get
import 'package:get/get.dart';
然后我们对MaterialApp
进行更改,所以我们的main.dart
文件现在看起来像这样:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
现在我们的应用程序已设置为支持 GetX 导航。 为了测试这一点,我们将在views/
目录中创建另一个视图。 我们将在about_page.dart
上调用它,它将包含以下代码:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class AboutPage extends StatelessWidget { final MyHomePageController controller = Get.put(MyHomePageController()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('About GetX'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(16.0), child: Text( 'GetX is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way.', ), ), ], ), ), ); } }
然后我们将转到MyHomePage
并添加一个按钮,按下该按钮会将我们导航到AboutPage
。 像这样。 该按钮应位于 Obx 小部件下方。 这里是:
FlatButton(onPressed: () {}, child: Text('About GetX'))
我们还需要在MyHomePage
文件的顶部导入AboutPage
:
import './about_page.dart';
要告诉 GetX 导航到AboutPage
,我们只需要一行代码:
Get.to(AboutPage());
让我们将它添加到FlatButton
小部件的onPressed
回调中,如下所示:
FlatButton( onPressed: () { Get.to(AboutPage()); }, child: Text('About GetX'))
现在保存应用程序时,您现在可以导航到AboutPage
。
您还可以选择用AboutPage
替换MyHomePage
视图,这样用户将无法通过点击设备返回按钮导航回上一页。 这对于登录屏幕等屏幕很有用。 为此,请将onPressed
处理程序的内容替换为以下代码:
Get.off(AboutPage());
这将弹出MyHomePage
视图并将其替换为AboutPage
。
现在我们可以导航到AboutPage
,我认为能够回到MyHomePage
执行此操作并不会那么糟糕,我们将在AboutPage
中的 Padding 小部件之后添加一个按钮,并在它的onPressed
处理程序中进行调用到Get.back()
导航回MyHomePage
:
FlatButton( onPressed: () { Get.back(); }, child: Text('Go Home') )
小吃店
在 Flutter 中,通常要显示 Snackbar,您需要编写如下内容:
final snackBar = SnackBar(content: Text('Yay! A SnackBar!')); // Find the Scaffold in the widget tree and use it to show a SnackBar. Scaffold.of(context).showSnackBar(snackBar);
您可以观察到我们仍然依赖于context
属性。 让我们看看如何在 GetX 中实现这一点。 进入MyHomePage
视图并在我们添加的最后一个按钮下方添加另一个FlatButton
小部件。 这是按钮的片段:
FlatButton( onPressed: () { // TODO: Implement Snackbar }, child: Text('Show Snackbar'))
让我们显示消息“耶! 很棒的 GetX 小吃店。 在 onPressed 处理函数中添加以下代码行:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar');
运行你的应用程序,当你点击“Show Snackbar button”时,你会在你的应用程序顶部看到一个snackbar!
看看我们如何减少在 Flutter 应用程序中显示快餐栏所需的行数? 让我们在 Snackbar 上做更多的自定义; 让我们让它出现在应用程序的底部。 将代码更改为:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, );
保存并运行您的应用程序,Snackbar 现在将出现在应用程序的底部。 我们如何改变 Snackbar 的背景颜色,因为它现在是透明的。 我们将从 Flutter 的Colors
类中将其更改为amberAccent
颜色。 将代码更新为:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent );
总体而言,按钮代码应如下所示:
FlatButton( onPressed: () { Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent); }, child: Text('Show Snackbar'))
对话
GetX 提供了一种在 Flutter 中创建 AlertDialog 的简单方法。 让我们看看它的实际效果。 在前一个按钮下方创建另一个按钮:
FlatButton( onPressed: () { // TODO: Show alert dialog }, child: Text('Show AlertDialog'))
让我们调用 GetX 来显示一个警告对话框:
Get.defaultDialog();
这将显示一个默认的警报对话框,可以通过在对话框之外点击来关闭它。 您可以在一行代码中看到我们如何拥有一个有效的警报对话框。 让我们稍微定制一下。 让我们更改标题和消息:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert');
保存并运行您的应用程序,当您点击“Show AlertDialog”按钮时,您将看到更改。 我们可以像这样添加确认和取消按钮:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert', textConfirm: 'Okay', confirmTextColor: Colors.amberAccent, textCancel: 'Cancel');
有很多方法可以自定义 GetX 对话框,并且 API 非常直观和简单。
结论
GetX 旨在提高 Flutter 开发人员在构建功能时的工作效率。 GetX 无需搜索执行状态管理、导航管理等所需的样板,而是提供了一个简单直观的 API 来实现这些活动,而不会牺牲性能。 本文向您介绍 GetX 以及如何开始在您的 Flutter 应用程序中使用它。
- 您可以在这里找到演示 →