Flutter 應用程序中的 GetX 包入門

已發表: 2022-03-10
快速總結 ↬ GetX 是一個額外的輕量級解決方案,用於 Flutter 應用程序的狀態、導航和依賴項管理。 在本文中,我們將了解它的優勢、特性以及如何在 Flutter 應用程序中開始使用它。

Flutter 是構建真正跨平台的原生應用程序的最快方式之一。 它提供的功能允許開發人員為其用戶構建真正漂亮的 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');

運行您的應用程序,當您單擊“顯示 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 應用程序中使用它。

  • 您可以在這裡找到演示 →