How the GetX easy to use in Flutter

1. Introduction

Flutter is a powerful and cross-platform mobile app development framework, it’s easy to learn and build a nice user interface. But, if you are an experienced c#/Java programmer (it’s me~ ha ha), maybe you will be a little uncomfortable, because Flutter is a reactive programming framework, reactive programming is a declarative programming paradigm that is based on the idea of asynchronous event processing and data streams.

So, if you want to update the UI in Flutter, you need to update the state to refresh the layout, the programming logic will be different with C# or Java, so luckily there are many state management frameworks to help do that, but these frameworks are not easy to understand and use except GetX.

GetX is a fast, stable, and light state management library in Flutter. There are so many State Management libraries in Flutter like MobX, BLoC, Redux, Provider, etc. GetX is also a powerful micro framework and using this, we can manage states, make routing, and can perform dependency injection.

Do you want to be a good trading in cTrader?   >> TRY IT! <<

2. Why Getx

GetX is focused on performance and minimum consumption of resources. One of the key performance advantages of GetX lies in its minimal overhead. By minimizing unnecessary re-renders and widget rebuilds, GetX significantly reduces the computational burden on your application, resulting in faster rendering and improved overall performance.

In addition, GetX leverages the power of efficient dependency injection. Its lightweight dependency injection mechanism enables the creation and management of dependencies without compromising performance. By efficiently managing dependencies, GetX helps eliminate unnecessary object instantiations and ensures efficient memory utilization.

3. Base Usages

3.1 Installing

Add Get to your pubspec.yaml:

dependencies:
    get: 4.6.6

and import the lib in your dart file

import 'package:get/get.dart';

3.2 State Management

GetX is easy to use, for example, you can define a variable with .obs to make it observable

var isEnabled = false.obs;

...

//change to enable
isEnabled.value = true;

and use Obx(() => ) in UI to monitor the changes

return Scaffold(
      appBar: AppBar(
        title: const Text('Test'),
        centerTitle: true,
      ),
      body: Stack(
        children: [
          Obx(
            () => controller.isEnabled.value 
                ? ListView(
                    children: <Widget>[
                     ...
                    ],
                  )
                : const SizedBox.shrink(),
          ),
        ],
      ), 
    );
  }

for the above example, if the isEnabled value changed to true, then will show the ListView data, just so easy, right?

3.3 Route Management

Navigation is very important in an App, GetX can help you easy to manage it. For example:

//navigate to a next page
Get.to(NextPage());

//navigate to next page by name
Get.tonamed('/next');

//beck to previous page or close snackbar,dialogs...
Get.back();

//to go to the next page and no option to go back to the previous page (for use in SplashPage, login Page, etc.)
Get.off(NextPage());

//to go to the next screen and cancel all previous routes (useful in shopping carts, polls, and tests)
Get.offAll(NextPage());

Ok, you can find more detailed usages in the official project website, and I will show another tip what I am using 🙂

4. Other Usages

4.1 Using in bottomNavigationBar

Most of the time, we just need to bind the dependencies in main.dart when starting the app, but if you are using the bottomNavigationBar, you also need to bind the dependence in the bottom navigation main page, for example the below structure

dashboard (bottomNavigationBar main page)
    -- home
        -- product1
            -- product1_detail
        -- product2
            -- product1_detail
    -- settings

so the bindings in dashboard should be like below

class DashboardBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<DashboardController>(
      () => DashboardController(),
    );
    Get.lazyPut<HomeController>(
      () => HomeController(),
    );
    Get.lazyPut<Product1Controller>(
      () => Product1Controller(),
    );
    Get.lazyPut<Product2Controller>(
      () => Product2Controller(),
    );
  }
}

and when you want to navigate to the product1 detail page from product1, you need to add the binding before go

return InkWell(
onTap: () {
  Get.lazyPut<Product1DetailController>(
    () => Product1DetailController(),
  );
  Get.to(() => const Product1DetailPage());
},

4.2 Using service for the common functions

GetX Service useful to let you make some common functions, you can handle the same lifecycle (onInit(), onReady(), onClose()) as controller, and you can get the service anywhere with Get.find(). For example, create a local storage service for handle the SharedPreferences functions

class LocalStorageService extends GetxService {
Future<T?> getValue<T>(
    LocalStorageKeys key, [
    T Function(Map<String, dynamic>)? fromJson,
  ]) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    switch (T) {
      case int:
        return prefs.getInt(key.name) as T?;
      case double:
        return prefs.getDouble(key.name) as T?;
      case String:
        return prefs.getString(key.name) as T?;
      case bool:
        return prefs.getBool(key.name) as T?;
      default:
        assert(fromJson != null, 'fromJson must be provided for Object values');
        if (fromJson != null) {
          final stringObject = prefs.getString(key.name);
          if (stringObject == null) return null;
          final jsonObject = jsonDecode(stringObject) as Map<String, dynamic>;
          return fromJson(jsonObject);
        }
    }
    return null;
  }

  void setValue<T>(LocalStorageKeys key, T value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    switch (T) {
      case int:
        prefs.setInt(key.name, value as int);
        break;
      case double:
        prefs.setDouble(key.name, value as double);
        break;
      case String:
        prefs.setString(key.name, value as String);
        break;
      case bool:
        prefs.setBool(key.name, value as bool);
        break;
      default:
        assert(
          value is Map<String, dynamic>,
          'value must be int, double, String, bool or Map<String, dynamic>',
        );
        final stringObject = jsonEncode(value);
        prefs.setString(key.name, stringObject);
    }
  }
}

and init the service in main.dart

Get.put(LocalStorageService());

then you can use it anywhere (including in other services)

//get the service
var localStorage = Get.find<LocalStorageService>();

...

//save the value
localStorage.setValue<String>('currentLanguage', 'en');

//get the value
var currentLanguage =
      await localStorage.getValue<String>('currentLanguage');

4.3 Using the dialog

GetX support to use the popup dialog, you can easily use the default dialog below

Get.defaultDialog(
    title: 'Title',
    titleStyle: const TextStyle(color: Colors.red),
    middleText: 'Messages');

This is only the normal alert dialog, if you want to use a custom style, you can use the below

Get.dialog(
  Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Padding(
        padding: const EdgeInsets.symmetric(horizontal: 40),
        child: Container(
          decoration: const BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(
              Radius.circular(20),
            ),
          ),
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Material(
              child: 

              //your layout widgets

            ),
          ),
        ),
      ),
    ],
  ),
);

as you can see, you can put any widgets in Get.dialog(), so this is not only a dialog but also a popup page 🙂

and you can create the dialog as a service, there is a complete custom dialog service below:

enum DialogType {
  info,
  success,
  error,
  warning,
}


class DialogService extends GetxService {
  showAlert(
    String title,
    String message, {
    DialogType dialogType = DialogType.info,
    Function? callback,
  }) {
    IconData iconData = Icons.info;
    Color iconColor = Colors.blueGrey;
    if (dialogType == DialogType.error) {
      iconData = Icons.error;
      iconColor = Colors.red;
    } else if (dialogType == DialogType.warning) {
      iconData = Icons.warning;
      iconColor = Colors.yellow;
    } else if (dialogType == DialogType.success) {
      iconData = Icons.done_rounded;
      iconColor = Colors.green;
    }

    Get.dialog(
      Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: Container(
              decoration: const BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(
                  Radius.circular(20),
                ),
              ),
              child: Padding(
                padding: const EdgeInsets.all(20.0),
                child: Material(
                  child: Column(
                    children: [
                      const SizedBox(height: 10),
                      Icon(
                        iconData,
                        color: iconColor,
                        size: 50,
                      ),
                      const SizedBox(height: 10),
                      Text(
                        title,
                        style: const TextStyle(
                            fontSize: 24, fontWeight: FontWeight.bold),
                        textAlign: TextAlign.center,
                      ),
                      const SizedBox(height: 20),
                      Text(
                        message,
                        style: const TextStyle(fontSize: 18),
                        textAlign: TextAlign.center,
                      ),
                      const SizedBox(height: 50),
                      //Buttons
                      Row(
                        children: [
                          Expanded(
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                foregroundColor: const Color(0xFFFFFFFF),
                                backgroundColor: Colors.blue,
                                minimumSize: const Size(0, 45),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(8),
                                ),
                              ),
                              onPressed: () {
                                callback != null ? callback() : null;
                              },
                              child: Text(
                                style: const TextStyle(fontSize: 18),
                                LabelKeys.ok.tr,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

you can use it anywhere

final dialog = Get.find<DialogService>();


//show the normal alert
dialog.showAlert(
  'Title',
  'This is a normal info alert'
);

//show the error alert
dialog.showAlert(
  'Error',
  'This is an error alert',
  dialogType: DialogType.error
);

5. Advanced Apis

There are also many advanced APIs that can be use, such like

// give the current args from currentScreen
Get.arguments

// give name of previous route
Get.previousRoute

// give the raw route to access for example, rawRoute.isFirst()
Get.rawRoute

// give access to Routing API from GetObserver
Get.routing

// check if snackbar is open
Get.isSnackbarOpen

// check if dialog is open
Get.isDialogOpen

// check if bottomsheet is open
Get.isBottomSheetOpen

//Check in what platform the app is running
GetPlatform.isAndroid
GetPlatform.isIOS
GetPlatform.isMacOS
GetPlatform.isWindows
GetPlatform.isLinux
GetPlatform.isFuchsia

//Check the device type
GetPlatform.isMobile
GetPlatform.isDesktop
//All platforms are supported independently in web!
//You can tell if you are running inside a browser
//on Windows, iOS, OSX, Android, etc.
GetPlatform.isWeb


// Equivalent to : MediaQuery.of(context).size.height,
// but immutable.
Get.height
Get.width

// Gives the current context of the Navigator.
Get.context

// Gives the context of the snackbar/dialog/bottomsheet in the foreground, anywhere in your code.
Get.contextOverlay

...

you can find more in here

6. Conclusion

GetX is powerful, it’s saved my many times, and it’s easy to understand, it also has a highly active and helpful community, you can find the solutions in their community if there are any problems, and you also can install the vs-code extension to help to build the GetX project. Please let me know if you have another opinion of GetX 🙂

Loading

Views: 12
Total Views: 609 ,

Oh hi there 👋
It’s nice to meet you.

Sign up to receive awesome content in your inbox.

We don’t spam! Read our privacy policy for more info.

Oh hi there 👋 It’s nice to meet you.

Sign up to receive awesome content in your inbox.

We don’t spam! Read our privacy policy for more info.

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Thank you so much!