Current Path : /www/sites/www.coderblog.in/index/
Url:

NameSizeOptions
App_DataDIRnone
backupDIRnone
cgi-binDIRnone
cssDIRnone
imgDIRnone
metaDIRnone
wp-adminDIRnone
wp-contentDIRnone
wp-includesDIRnone
.htaccess3.35 KBDEL
.htaccess.bk1.84 KBDEL
404.html0.13 KBDEL
ads.txt1.07 KBDEL
favicon.ico2.19 KBDEL
index.php0.40 KBDEL
license.txt19.44 KBDEL
php.ini0.58 KBDEL
readme.html7.25 KBDEL
service.php0.00 KBDEL
web.config2.87 KBDEL
wp-activate.php7.21 KBDEL
wp-blog-header.php1.21 KBDEL
wp-comments-post.php2.27 KBDEL
wp-config-sample.php3.26 KBDEL
wp-config.php2.98 KBDEL
wp-cron.php5.49 KBDEL
wp-links-opml.php2.44 KBDEL
wp-load.php3.84 KBDEL
wp-login.php50.21 KBDEL
wp-mail.php8.52 KBDEL
wp-settings.php29.38 KBDEL
wp-signup.php33.71 KBDEL
wp-trackback.php4.98 KBDEL
xmlrpc.php3.13 KBDEL
Getx – Coder Blog https://www.coderblog.in Join the coding revolution! Learn, share, and grow together! Fri, 14 Jun 2024 01:31:35 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.1 Use the powerful theme framework in GetX https://www.coderblog.in/2024/04/use-the-powerful-theme-framework-in-getx/ https://www.coderblog.in/2024/04/use-the-powerful-theme-framework-in-getx/#comments Mon, 08 Apr 2024 03:59:05 +0000 https://www.coderblog.in/?p=1145 1. Introduction FlexColorScheme is a very powerful theme framework for Flutter, there is complete documentation and tutorials, and

<p>The post Use the powerful theme framework in GetX first appeared on Coder Blog.</p>

]]>
1. Introduction

FlexColorScheme is a very powerful theme framework for Flutter, there is complete documentation and tutorials, and there are many existing themes that can be used, you also can design your theme online.

FlexColorScheme is at its core an advanced ThemeData factory. It makes customization of ThemeData simpler. It does not expose everything you can do with ThemeData via its own APIs. Its focus is on things that are complex and tedious to do with ThemeData. You can further tune the produced ThemeData by using copyWith and ThemeData’s own APIs.

The Themes Playground is a visual web configuration tool for the FlexColorScheme API. It allows you to play with different styles interactively, and copy the FlexColorScheme API setup code for the theme you created. The Playground does not cover all APIs offered by FlexColorScheme, but most of them, certainly the most commonly used ones.

2. Use in GetX

Because GetX can easy to help with dynamic change and handle the theme, I will base it on my previous article “Create Flutter project with GetX Pattern” to show you how to use FlexColorScheme in GetX.

2.1 Get the themes from FlexColorScheme

Create the theme folder under /lib/app/ui/, go to FlexColorScheme‘s playground to design or choose the existing theme, and click the Copy theme code button, then you can easy to copy the theme codes.

the theme code should be like below:

// Theme config for FlexColorScheme version 7.3.x. Make sure you use
// same or higher package version, but still same major version. If you
// use a lower package version, some properties may not be supported.
// In that case remove them after copying this theme to your app.
theme: FlexThemeData.light(
  scheme: FlexScheme.orangeM3,
  surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
  blendLevel: 7,
  subThemesData: const FlexSubThemesData(
    blendOnLevel: 10,
    blendOnColors: false,
    useTextTheme: true,
    useM2StyleDividerInM3: true,
    adaptiveRadius: FlexAdaptive.excludeWebAndroidFuchsia(),
    alignedDropdown: true,
    useInputDecoratorThemeInDialogs: true,
  ),
  visualDensity: FlexColorScheme.comfortablePlatformDensity,
  useMaterial3: true,
  swapLegacyOnMaterial3: true,
  // To use the Playground font, add GoogleFonts package and uncomment
  // fontFamily: GoogleFonts.notoSans().fontFamily,
),
darkTheme: FlexThemeData.dark(
  scheme: FlexScheme.orangeM3,
  surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
  blendLevel: 13,
  subThemesData: const FlexSubThemesData(
    blendOnLevel: 20,
    useTextTheme: true,
    useM2StyleDividerInM3: true,
    adaptiveRadius: FlexAdaptive.excludeWebAndroidFuchsia(),
    alignedDropdown: true,
    useInputDecoratorThemeInDialogs: true,
  ),
  visualDensity: FlexColorScheme.comfortablePlatformDensity,
  useMaterial3: true,
  swapLegacyOnMaterial3: true,
  // To use the Playground font, add GoogleFonts package and uncomment
  // fontFamily: GoogleFonts.notoSans().fontFamily,
),
// If you do not have a themeMode switch, uncomment this line
// to let the device system mode control the theme mode:
// themeMode: ThemeMode.system,

but we still need to change something, we need to create a class to handle each theme, for the above theme code, we can create the class ThemeBrown below

create a file /lib/app/ui/theme/theme_brown.dart and past the theme code:

import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/material.dart';

class ThemeBrown {
  static ThemeData lightTheme() => FlexThemeData.light(
      scheme: FlexScheme.orangeM3,
      surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
      blendLevel: 7,
      subThemesData: const FlexSubThemesData(
        blendOnLevel: 10,
        blendOnColors: false,
        useTextTheme: true,
        useM2StyleDividerInM3: true,
        adaptiveRadius: FlexAdaptive.excludeWebAndroidFuchsia(),
        alignedDropdown: true,
        useInputDecoratorThemeInDialogs: true,
      ),
      visualDensity: FlexColorScheme.comfortablePlatformDensity,
      useMaterial3: true,
      swapLegacyOnMaterial3: true,
      // To use the Playground font, add GoogleFonts package and uncomment
      // fontFamily: GoogleFonts.notoSans().fontFamily,
    );

  static ThemeData darkTheme() => FlexThemeData.dark(
      scheme: FlexScheme.orangeM3,
      surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
      blendLevel: 13,
      subThemesData: const FlexSubThemesData(
        blendOnLevel: 20,
        useTextTheme: true,
        useM2StyleDividerInM3: true,
        adaptiveRadius: FlexAdaptive.excludeWebAndroidFuchsia(),
        alignedDropdown: true,
        useInputDecoratorThemeInDialogs: true,
      ),
      visualDensity: FlexColorScheme.comfortablePlatformDensity,
      useMaterial3: true,
      swapLegacyOnMaterial3: true,
      // To use the Playground font, add GoogleFonts package and uncomment
      // fontFamily: GoogleFonts.notoSans().fontFamily,
    );
}

as you can see, we put the light and dark theme to lightTheme and darkTheme method in ThemeBrown class, and then we can easy to use them later.

for example, I want to create 10 themes in my App, just repeat the above flow and create 10 theme classes and files

2.2 Create theme service

Because we need to handle multiple themes, we can create a service for handling the below theme logic:

  1. define the theme’s name
  2. get the theme by name
  3. get the current theme mode from storage

so the file should be /lib/app/data/service/theme_service.dart:

import 'package:get_storage/get_storage.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../ui/theme/theme_brown.dart';
import '../../ui/theme/theme_deepBlue.dart';
import '../../ui/theme/theme_gold.dart';
import '../../ui/theme/theme_green.dart';
import '../../ui/theme/theme_hippie_blue.dart';
import '../../ui/theme/theme_indigo.dart';
import '../../ui/theme/theme_orang.dart';
import '../../ui/theme/theme_purple.dart';
import '../../ui/theme/theme_red.dart';
import '../../ui/theme/theme_sakura.dart';

class ThemeService {
  //define each theme's name
  static const String Red = 'Red';
  static const String Indigo = 'Indigo';
  static const String HippieBlue = 'HippieBlue';
  static const String Green = 'Green';
  static const String DeepBlue = 'DeepBlue';
  static const String Sakura = 'Sakura';
  static const String Purple = 'Purple';
  static const String Brown = 'Brown';
  static const String Gold = 'Gold';
  static const String Orang = 'Orang';

  //use GetStorage to handle the current theme mode
  final _getStorage = GetStorage();
  final _storageKey = 'ThemeMode';
  static ThemeService instance = ThemeService._();
  // ignore: empty_constructor_bodies
  ThemeService._() {}
  set themeMode(ThemeMode themeMode) {
    if (themeMode == ThemeMode.system) {
      _getStorage.remove(_storageKey);
    } else {
      _getStorage.write(_storageKey, themeMode == ThemeMode.dark);
    }
    Get.changeThemeMode(themeMode);
  }

  ThemeMode get themeMode {
    switch (_getStorage.read(_storageKey)) {
      case true:
        return ThemeMode.dark;
      case false:
        return ThemeMode.light;
      default:
        return ThemeMode.system;
    }
  }

  //Get the theme by name and handle light and dark mode
  ThemeData getTheme(String name, {bool isDark = false}) {
    ThemeData currTheme = ThemeData();
    switch (name) {
      case Red:
        currTheme = isDark ? ThemeRed.darkTheme() : ThemeRed.lightTheme();
        break;
      case Indigo:
        currTheme = isDark ? ThemeIndigo.darkTheme() : ThemeIndigo.lightTheme();
        break;
      case HippieBlue:
        currTheme =
            isDark ? ThemeHippieBlue.darkTheme() : ThemeHippieBlue.lightTheme();
        break;
      case Green:
        currTheme = isDark ? ThemeGreen.darkTheme() : ThemeGreen.lightTheme();
        break;
      case DeepBlue:
        currTheme =
            isDark ? ThemeDeepBlue.darkTheme() : ThemeDeepBlue.lightTheme();
        break;
      case Sakura:
        currTheme = isDark ? ThemeSakura.darkTheme() : ThemeSakura.lightTheme();
        break;
      case Purple:
        currTheme = isDark ? ThemePurple.darkTheme() : ThemePurple.lightTheme();
        break;
      case Brown:
        currTheme = isDark ? ThemeBrown.darkTheme() : ThemeBrown.lightTheme();
        break;
      case Gold:
        currTheme = isDark ? ThemeGold.darkTheme() : ThemeGold.lightTheme();
        break;
      case Orang:
        currTheme = isDark ? ThemeOrang.darkTheme() : ThemeOrang.lightTheme();
        break;
    }

    return currTheme;
  }
}

2.3 Show the theme selection

We need to show the theme selection to the user to choose which theme they want to use, to simplify the operation, I use babstrap_settings_screen and hardcode to put the theme items in a ListView, of course you can use other way to present it.

below is only a code snippet for presenting one theme item with babstrap_settings_screen in ListView in UI page

/lib/app/ui/pages/settings_theme_page/settings_theme_page.dart

ListView(
  children: [
    SettingsGroup(
      items: [
        SettingsItem(
          onTap: () {
            controller.changeTheme(
                isDarkMode,
                ThemeService.Red,
                isDarkMode
                    ? ThemeRed.darkTheme()
                    : ThemeRed.lightTheme());
          },
          icons: CupertinoIcons.paintbrush_fill,
          iconStyle: IconStyle(
            iconsColor: Colors.white,
            withBackground: true,
            backgroundColor: Colors.red,
          ),
          title: LabelKeys.theme1.tr,
          trailing: Radio<String>(
            value: ThemeItem.Red,
            groupValue: controller.selectedValue.value,
            activeColor: Theme.of(context)
                .primaryColor, // Change the active radio button color here
            fillColor: MaterialStateProperty.all(Theme.of(context)
                .secondaryHeaderColor), // olor when selected
            splashRadius:
                20, // Change the splash radius when clicked
            onChanged: (value) {
              controller.changeTheme(
                  isDarkMode,
                  value!,
                  isDarkMode
                      ? ThemeRed.darkTheme()
                      : ThemeRed.lightTheme());
            },
          ),
        ),
      ],
    ),
  ],
)

and we can get the current theme mode by the below code

Brightness currentBrightness = MediaQuery.of(context).platformBrightness;
bool isDarkMode = currentBrightness == Brightness.dark;

and handle the backend logic in controller

/lib/app/controllers/settings_theme_controller.dart

class SettingsThemeController extends GetxController {
  //define a variable to save selected theme value
  var selectedValue = Global.defaultTheme.obs;
  //use the local storage to save the selected theme
  var localStorage = Get.find<LocalStorageService>();

  @override
  void onReady() async {
    super.onReady();

    //get the current theme from local storage
    var currTheme =
        await localStorage.getValue<String>(LocalStorageKeys.currentTheme);

    //set the current theme
    selectedValue.value = currTheme!;
  }

  //change the theme when user click the item
  void changeTheme(bool isDarkMode, String name, ThemeData theme) {
    selectedValue.value = name;

    localStorage.setValue<String>(LocalStorageKeys.currentTheme, name);
    Get.changeThemeMode(isDarkMode ? ThemeMode.dark : ThemeMode.light);
    Get.changeTheme(theme);
  }
}

2.4 Handle default theme when App startup

In the end, we need to handle the default theme or selected theme when the app starts. So we need to update the main.dart file

If you create the GetX project like this article, you should get something like the below code in the main.dart

void main() async {

    WidgetsFlutterBinding.ensureInitialized();
    DependecyInjection.init();

    runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {

    return ScreenUtilInit(
      builder: (_, __) {
        return GetMaterialApp(
          title: 'Win_reading_harry_potter',
          debugShowCheckedModeBanner: false,
          translations: Translation(),
          initialBinding: AppBindings(),
          initialRoute: AppRoutes.SPLASH,
          unknownRoute: AppPages.unknownRoutePage,
          getPages: AppPages.pages,
          builder: (_, child) {
            return MainLayout(child: child!);
          },
        );
      },
      //! Must change it to true if you want to use the ScreenUtil
      designSize: const Size(411, 823),
    );
  }
}

we need to add some codes to support the theme

void main() async {

  ...

  //get the selected theme from local storage
  var localStorage = LocalStorageService();
  var currTheme =
      await localStorage.getValue<String>(LocalStorageKeys.currentTheme);

 //if there is no theme for first time, then use the default theme
 if (currTheme == null) {
    currTheme = Global.defaultTheme;
    localStorage.setValue<String>(
        LocalStorageKeys.currentTheme, Global.defaultTheme);
  }

  //pass the current theme to material app
  runApp(MyApp(currTheme: currTheme));
}

so also update the below

class MyApp extends StatelessWidget {
  //support the parameter for setting the current theme
  const MyApp({super.key, this.currTheme});

  final String? currTheme;

 @override
  Widget build(BuildContext context) {
    //get the light and dark theme base on current theme
    ThemeData lightTheme = currTheme == null
        ? ThemeDeepBlue.lightTheme()
        : ThemeItem.getTheme(currTheme!);
    ThemeData darkTheme = currTheme == null
        ? ThemeDeepBlue.darkTheme()
        : ThemeItem.getTheme(currTheme!, isDark: true);

    return ScreenUtilInit(
      builder: (_, __) {
        return GetMaterialApp(
          title: 'Win_reading_harry_potter',
          debugShowCheckedModeBanner: false,
          theme: lightTheme,    //set the light theme
          darkTheme: darkTheme, //set the dark theme
          themeMode: ThemeService.instance.themeMode, //set the default theme mode
          translations: Translation(),
          initialBinding: AppBindings(),
          initialRoute: AppRoutes.SPLASH,
          unknownRoute: AppPages.unknownRoutePage,
          getPages: AppPages.pages,
          builder: (_, child) {
            return MainLayout(child: child!);
          },
        );
      },
      //! Must change it to true if you want to use the ScreenUtil
      designSize: const Size(411, 823),
    );
  }
}

Done!

3. Conclusion

FlexColorScheme can help to make beautiful Flutter Material Design themes, and GetX and easy to handle and change the theme dynamic, so if you combine them, you will find that a great job!

Loading

<p>The post Use the powerful theme framework in GetX first appeared on Coder Blog.</p>

]]>
https://www.coderblog.in/2024/04/use-the-powerful-theme-framework-in-getx/feed/ 20
Create Flutter project with GetX Pattern https://www.coderblog.in/2024/03/create-flutter-project-with-getx-pattern/ https://www.coderblog.in/2024/03/create-flutter-project-with-getx-pattern/#comments Tue, 19 Mar 2024 03:58:47 +0000 https://www.coderblog.in/?p=1139 1. Introduction In my previous article, I introduced the GetX framework, but there are several parts needed to

<p>The post Create Flutter project with GetX Pattern first appeared on Coder Blog.</p>

]]>
1. Introduction

In my previous article, I introduced the GetX framework, but there are several parts needed to create and handle in the GetX project, so today, let me show you how to create a good pattern with GetX project so that we can easier to use it 😃

2. The Architecture

A good architecture can help you organize your code and easy to maintain. There are many great architectures for Flutter projects, and you just need to find one of to suitable for you 🙂

I found the below architecture is suitable for me

the main structure is organized below folders:

/lib
    /app
        /bindings
        /config
        /controllers
        /data
        /routes
        /translation
        /ui
    mail.dart

GetX separates the view and controller just like the MVC pattern, so we can also put these in a difference folder for decoupling them.

/bindings      # GetX controller bindings
/controllers   # GetX controller
/routes        # GetX routes
/ui            # GetX views and layouts

And below folders for other things:

/config        # The global config or app information into `/config` folder. 
/data          # Handle database and some core logics
/translation   # Translation for support multiple languages in your project

The details of /data folder

/data
    /database    # Database handler or logic
    /failures    # Handle the failures logic for calling API 
    /helpers     # Helper methods of data handler
    /models      # The models of the project 
    /provider    # The providers of the project
    /services    # The services of the project

The details of /ui folder

/ui
    /global_widgets    # The global widgets
    /layouts           # If you want to handle different layouts in your project, you can use it
    /pages             # The UI presentation, like the viewer in MVC
    /theme             # The theme data or style
    /utils             # The utility methods

Of course, you may not need to use all of these folders in your actual project, just based on what you need.

3. Create the GetX project structure

Next, we need to create these folder structures. But it would be troublesome to create these manually every time, so we can use the VS Code extension: GetX Helper Awesome

Input the below command in VS Code, it will help to create and init the above project structure:

It not only creates the folder structure but also helps to create the GetX structure and codes. It will update your main.dart and use ScreenUtilInit to make a responsive app

You can use the below commands to create other items of the structure

but it will generate the Model and Respoistory based on Firestore, so if you don’t use Firestore library, you need to modify your codes after generating. By the way, there is a little bug in generating the route, it will miss a single quote in the route’s name.

3.1 Command Layout

There is a layout concern with this pattern, I think this is good for handler multiple layout cases. (e.g the login page and user page will have difference common layouts)

You can find the below main_layout.dart file after the init project structure in /ui/layouts folder

and other pages will be based on this main layout, for example, the home_page.dart in /ui/pages/home_page folder

as you can see, you can see different common layouts for each page. The folder structure would be below

4. Conclusion

A good architecture and project structure are critical in Flutter development to enhance maintainability, scalability, code reusability, testability, collaboration, and performance. It sets a solid foundation for building high-quality apps that can evolve, scale, and be maintained effectively over time. So you should find a suitable structure for yourself, and use the VS Code extension can quick and easy to do that 😁

Loading

<p>The post Create Flutter project with GetX Pattern first appeared on Coder Blog.</p>

]]>
https://www.coderblog.in/2024/03/create-flutter-project-with-getx-pattern/feed/ 14
How the GetX easy to use in Flutter https://www.coderblog.in/2023/12/how-the-getx-easy-to-use-in-flutter/ https://www.coderblog.in/2023/12/how-the-getx-easy-to-use-in-flutter/#comments Mon, 11 Dec 2023 02:44:28 +0000 https://www.coderblog.in/?p=1112 1. Introduction Flutter is a powerful and cross-platform mobile app development framework, it’s easy to learn and build

<p>The post How the GetX easy to use in Flutter first appeared on Coder Blog.</p>

]]>
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.

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

<p>The post How the GetX easy to use in Flutter first appeared on Coder Blog.</p>

]]>
https://www.coderblog.in/2023/12/how-the-getx-easy-to-use-in-flutter/feed/ 9