preface

This article is based on the latest official stable release get: ^4.3.8

This series of courses will be explained in the simplest way, even with zero foundation can be easily mastered, the full text is simple, each chapter will have a case to show the effect and how to use.

The entire course series is minimal, and if you’re willing to spend two hours learning GetX, you’ll be able to easily master it and apply it to your enterprise projects.

Video Tutorial Address

Video Tutorial Address

By the end of this course series, you will have learned:
  • Know what GetX is
  • Use a Snackbar
  • Can use Dialog
  • Will use BottomSheet
  • Use Navigation
  • Can use Obx responsive state management
  • Can use GetXController (three ways to use GetBuilder, Event Listener, lifecycle, UniqueID)
  • Language internationalization configuration
  • Dependency injection
  • GetX Service
  • GetX Binding
  • GetX gets the API interface data and displays it
  • Get storage and mail validation
  • GetView and GetWidget
  • Get Cli scaffolding and common commands
  • GetX uses GetConnect and StateMixin to get API data

Why are we doing this course series?

At present, I can’t find a good comprehensive tutorial on GetX in the market. If I only read the official documentation to understand, it will take a long time to learn. Video is either too long and costly to learn. Or it’s scattered, like a headless fly. Therefore, I simply create a course by myself. The course series is simple and deep, which is convenient for everyone to have a systematic understanding of GetX. It took me a lot of time to explain the series, but as long as it’s helpful and you can benefit from it, that’s fine.

What is GetX?

GetX Chinese official document pub address

  • GetX is a lightweight and powerful solution for Flutter: high-performance state management, intelligent dependency injection, and convenient route management.
  • GetX has three basic principles:
    • Performance: GetX focuses on performance and minimal resource consumption. GetX’s packaged APK footprint and runtime memory footprint are comparable to other state management plug-ins. If you’re interested, here’s a performance test.
    • Efficiency: GetX’s syntax is very simple and maintains extremely high performance, which can greatly reduce your development time.
    • Structure: GetX completely decouples the interface, logic, dependencies, and routing, making it cleaner to use, clearer to logic, and easier to maintain code.

Why use GetX?

We know that there are many frameworks for state management, which are relatively complex using native ChangeNotifier to update widgets. If the business logic is complex, this approach is fatal.

Other state managers are good, but with subtle differences.

  • BLoC is very safe and efficient, but very complex for beginners, which makes it impossible to develop with Flutter.
  • MobX is easier than BLoC and responsive, almost perfect, but you need to use a code generator, which reduces productivity for large applications because you need to drink a lot of coffee until your code is influtter cleanThen it’s ready again (it’s not MobX’s fault, codeGen is really slow!) .
  • The Provider uses the InheritedWidget to pass the same listener to resolve the ChangeNotifier issue reported above, meaning that any access to its ChangeNotifier class must be within the Widget tree.

GetX reactive state manager

Reactive programming may sound unfamiliar to many people because of its complexity, but GetX makes reactive programming very simple. Reactive programming with Get is as easy as using setState.

  • You don’t need to create StreamControllers.
  • You don’t need to create a StreamBuilder for each variable.
  • You don’t need to create a class for each state.
  • You don’t need to create a GET for an initial value.

The installation

Add GetX to your pubspec.yaml file.

dependencies:
  get: ^4.38.
Copy the code

Import in the required file and it will be used.

import 'package:get/get.dart';
Copy the code

Introduce Snackbar

If you want to trigger certain events in your application and need to pop up a quick message, Snackbar is the best choice. Let’s take a look at GetX’s use of Snackbar.

Basic use of Snackbar

Step 1: Application entry setup

When we import the dependencies, we make GetMaterialApp the top layer of the application, as shown below

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"),),),); }}Copy the code

Step 2: Call the snackbar

We can display the snackbar with get.snackbar (), as shown below

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 title"."Welcome to Snackbar.");
                },
                child: Text("Display Snackbar"() [(), ((), ((), ((), ((), () }}Copy the code

Results show

If you run the code, congratulations, you already know how to display snackbar with GetX. You get the following result:

Snackbar properties and description

There are 38 properties in total,

field attribute describe
title String Pop-up title text
message String Pop-up message text
colorText Color Title and Message text colors
duration Duration Duration of Snackbar pop-up (default: 3 seconds)
instantInit bool Snackbar can be placed in initState when false, which defaults to true
snackPosition SnackPosition When the pop-up position, there are two options [TOP, BOTTOM] default TOP
titleText Widget Pops up the title component. Setting this property invalidates the title property
messageText Widget Component of a pop-up message. Setting this property invalidates the messageText property
icon Widget Pop-up icon, displayed to the left of title and message
shouldIconPulse bool Whether the icon blinks when it is displayed. Default value: False
maxWidth double Maximum width of Snackbar
margin EdgeInsets Snackbar margin, zero by default
padding EdgeInsets Snackbar inner margin, default EdgeInsets. All (16)
borderRadius double Border rounded corner size, default 15
borderColor Color The color of the border must be set to borderWidth otherwise it has no effect
borderWidth double The line width of the border
backgroundColor Color Background color: color.grey.withopacity (0.2)
leftBarIndicatorColor Color The color of the left indicator
boxShadows List Snackbar shadow color
backgroundGradient Gradient The linear color of the background
mainButton TextButton Main button, usually display send and confirm buttons
onTap OnTap Click the Snackbar event callback
isDismissible bool Allows you to dismissDirection with the Snackbar gesture closed
showProgressIndicator bool Whether to display a progress bar indicator. Default is false
dismissDirection SnackDismissDirection Snackbar closes in the direction
progressIndicatorController AnimationController Animation controller for progress bar indicator
progressIndicatorBackgroundColor Color Background color of the progress bar indicator
progressIndicatorValueColor Animation Background color for progress bar indicator, Animation
snackStyle SnackStyle Will the Snackbar be attached to the edge of the screen
forwardAnimationCurve Curve Snackbar pops animation, default Curves. EaseOutCirc
reverseAnimationCurve Curve Snackbar disappearing animation, default Curves. EaseOutCirc
animationDuration Duration Snackbar pop-up and hours of animation duration, default 1 second
barBlur double Blur of Snackbar background
overlayBlur double Frosted glass effect value when pop-up, default 0
snackbarStatus SnackbarStatusCallback Event callback when the Snackbar pops up or disappears (about to open, Opened, About to close, Closed)
overlayColor Color Background color of frosted glass when pop-up
userInputForm Form User input form

Dialog is introduced

The bottom layer of Dialog is actually the encapsulation of AlertDialog, which is generally used for the pop-up box of double confirmation. For example, when clicking a button to submit data, the user needs to confirm twice to prevent misoperation.

Use the Dialog

Step 1: Application entry setup

When we import the dependencies, we make GetMaterialApp the top layer of the application, as shown below

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

Step 2: Call Dialog

We can display a dialog with get.defaultDialog (), as shown below

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 (" display Dialog "))],),),); }}Copy the code

Results show

If you run the code, congratulations, you already know how to display a dialog using GetX. You get the following result:

Dialog properties and description

There are 25 attributes in total

field attribute describe
title String Popup title, default (Alert)
titlePadding EdgeInsetsGeometry Inner margin of title, default (edgeinsets.all (8))
titleStyle TextStyle Heading style
middleText String The text displayed in the middle content area
middleTextStyle TextStyle The text style displayed in the middle content area
content Widget Popup content, the value set after middleText will be invalid
contentPadding EdgeInsetsGeometry Inner margin of content, default (edgeinsets.all (8))
onConfirm VoidCallback Confirm button callback
onCancel VoidCallback Cancel button callback
onCustom VoidCallback Custom button callback
cancelTextColor Color Uncolor the button text
confirmTextColor Color Confirm the color of the button text
textConfirm String Confirm the text of the button
textCancel String Cancel button text
textCustom String Custom button text
confirm Widget Identify the components of the button
cancel Widget Cancel button component
custom Widget Components for customizing buttons
backgroundColor Color The background color of the pop-up box
barrierDismissible bool Can I close the popover by clicking on the background
buttonColor Color Button text color, depending on the button type to set different positions
radius double The size of the rounded corner of the pop-up box. The default value is 20
actions List Add additional subcomponents
onWillPop WillPopCallback Do a few things before intercepting is turned off
navigatorKey GlobalKey The key used to open the dialog box

BottomSheet introduction

BottomSheet is a component that pops up at the bottom, which is often used for radio selection and secondary verification of verification codes. In GetX, the BottomSheet pops up at the bottom to customize the effect of the popup through route push.

BottomSheet use

We can easily call bottomSheet() using GetX without passing in the context, so let me show you an example where we can pop up bottomSheet using GetX and easily switch themes

Step 1: Application entry setup

When we import the dependencies, we make GetMaterialApp the top layer of the application, as shown below

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

Step 2: Call BottomSheet

We can display bottomSheet with get.bottomsheet (), as shown below

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(" daytime Mode "), onTap: () {get.changetheme (themedata.light ());},), ListTile(leading: Icon(Icons. Wb_sunny), title: Text(" dark mode "), onTap: () { Get.changeTheme(ThemeData.dark()); }, ) ], ), ) ); }, child: Text("Bottom Sheet")) ], ), ), ); }}Copy the code

Results show

If you run the code, congratulations, you can already display BottomSheet with GetX. You get the following result:

BottomSheet properties and description

field attribute describe
bottomsheet Widget Widget component that pops up
backgroundColor Color The background color of Bottomsheet
elevation double The shadow of bottomsheet
persistent bool Whether to add it to a route
shape ShapeBorder Border shape, generally used for rounded corner effect
clipBehavior Clip Way of tailoring
barrierColor Color The background color of the pop-up layer
ignoreSafeArea bool Whether to ignore security adaptation
isScrollControlled bool Whether full screen pop-up is supported. The default value is false
useRootNavigator bool Whether to use root navigation
isDismissible bool Click background to see if it can be turned off, default true
enableDrag bool Whether you can drag to close. Default: true
settings RouteSettings Routing setting
enterBottomSheetDuration Duration The animation time when Bottomsheet enters
exitBottomSheetDuration Duration The animation time when Bottomsheet exits

Navigation

It is very simple to use GetX for route jump, just need to call get.to () for route jump, and the system route jump needs to write eight lines of code, which is unbearable, and involves jump animation Settings, animation duration definition, animation curve and other Settings, which is more complex. GetX encapsulates Navigation for us, which can jump without context, and can easily use jump animation, etc.

Navigation- Use the to method to jump to the route

Step 1: Application entry setup

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

Step 2: Call the to method

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("Jump to home page"() [(), (), (); }}Copy the code

Results show

Navigation- Use toNamed to navigate

Step 1: Application entry setup

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

Step 2: Call 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("Jump to home page"() [(), (), (); }}Copy the code

Results show

Obx responsive state management

introduce

Reactive programming may sound unfamiliar to many people because of its complexity, but GetX makes reactive programming very simple.

  • You don’t need to create StreamControllers.
  • You don’t need to create a StreamBuilder for each variable.
  • You don’t need to create a class for each state.
  • You don’t need to create a GET for an initial value.

Reactive programming with Get is as easy as using setState.

Three ways to define an Obx variable

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

// The second way is to use Rx, specifying the generic Rx
      
       .
      
// 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>>({});
// Custom class - can be any class
// final user = Rx<User>();

// The third, more practical, simpler, and preferable approach is simply to add.obs as the value attribute.
// 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;
// Custom class - can be any class
// final user = User().obs;
Copy the code

Counter case

Step 1: Application entry setup

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

Step 2: Declare the Rx variable and the method to change the counter

RxInt count = RxInt(0);
// var count = Rx<double>(0);
// var count = 0.obs;

void increment() {
  count++;
}
Copy the code

Step 3: Use Obx to listen for value changes

Obx(() => Text(
  "Count has the value:$count",
  style: TextStyle(color: Colors.red, fontSize: 30))),Copy the code

The complete code

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-- counter"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Obx(() => Text(
              "Count has the value:$count",
              style: TextStyle(color: Colors.red, fontSize: 30),
            )),
            SizedBox(height: 20,),
            ElevatedButton(
              onPressed: () {
                increment();
              },
              child: Text("Click and I add one."() [(), (), (); }}Copy the code

Results show

Custom class cases

Step 1: Application entry setup

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

Step 2: Create the Teacher class

import 'package:get/get.dart';

class Teacher {

  / / rx variables
  var name = "Jimi".obs;
  var age = 18.obs;

  // Constructor created
  // var name;
  // var age;
  // Teacher({this.name, this.age});
}
Copy the code

Step 3: Monitor Teacher status change


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-- Custom class"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Obx(() => Text(
              "My name is${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("Convert to uppercase"() [(), (), (); }}Copy the code

Results show

conclusion

From this chapter, we know GetX is a high-performance state management, intelligent dependency injection and convenient route management. We introduce what GetX is and how to use it, including Snackbar, Dialog, BottomSheet, Navigation, Obx and so on. Using GetX minimizes our code.