Giter Club home page Giter Club logo

sleppy_medic's Introduction

Flutter GetX Template

Flutter Getx template to make starting project fast and easy .

Introduction

We all face the same problem when we want to start a new project we have to take care of some repeatable things such as

  • Theme (light/dark) & store current theme in shared pref ๐ŸŒ’
  • Localization & store the current locale in shared pref ๐Ÿ…ฐ๏ธ
  • Firebase Messaging ๐Ÿ“จ
  • Notifications setup ๐Ÿ””
  • Safe api requests & error handling ๐Ÿ”
  • Changing between widgets during api call (loading,success,failed..etc) ๐Ÿ˜ด
  • Snackbar,Toasts & in app notifications ๐Ÿช–
  • Making app more responsive and stop font scaling โš–๏ธ This project will take care of all this repeatable things so you can start your project in few steps and you will have all the mentioned points set up and ready to use ๐Ÿ˜Ž

Acknowledgment

Project was created using get_cli which is a great tool helping you to (start project,create screens/controllers, handling DI)..etc and we will list other packages that helped to create this skeleton

Clone and start project

Before discovering folders lets first perform some actions to make the project ready to launch

  • first run this command it will generate hive type adapters (for our custom classes that we want to store locally)

    flutter packages pub run build_runner build --delete-conflicting-outputs
    

    if you don't want to use hive comment this line in main.dart

    await MyHive.init(adapters: [UserModelAdapter()]);
  • To make your app responsive and look exactly as your (xd,figma..etc) design you need to set artbord size for flutter_ScreenUtil in main.dart

    ScreenUtilInit(
      designSize: const Size(375, 812), // change this to your xd artboard size
  • FCM & Awesome Notifications are combined at the same class so when ever you connect your app to firebase your app will be ready to receive notifications you don't need to do anything except sending fcm notification to your api via implementing the method (sendFcmTokenToServer) which is inside FcmHelper class ๐Ÿ˜Ž

    static _sendFcmTokenToServer(){
        var token = MySharedPref.getFcmToken();
        // TODO SEND FCM TOKEN TO SERVER
    }
  • Change app package name

    flutter pub run change_app_package_name:main com.new.package.name
    
  • Change app name

    flutter pub run rename_app:main all="My App Name"
    
  • Change app launch icon (replace assets/images/app_icon.png with your app icon) then run this command

    flutter pub run flutter_launcher_icons:main
    
  • Change app splash screen (replace assets/images/splash.png with your app splash logo) then run this command

    flutter pub run flutter_native_splash:create
    
  • FCM: firebase has recently added (add flutter app) to your firebase which will make adding our flutter(android/ios) app to firebase take only 2 steps ๐Ÿ”ฅ but first you need to download Firebase CLI and in the terminal execute:

    dart pub global activate flutterfire_cli
    

    then follow the firebase guid you will get command similar to this one

    flutterfire configure --project=flutter-firebase-YOUR_PROJECT_ID
    

    and that's it! your project is now connected to firebase and fcm is up and ready to get notifications

Quick Start

  • Responsive app: to make your app responsive you need to get advantage of using flutter_ScreenUtil so instead of using normal double values for height,width,radius..etc you need to use it like this
200.w // adapted to screen width
100.h // /Adapted to screen height
25.sp // adapter font size
10.r // adapter radius
// Example
Container(
    height: 100.h,
    width: 200.w,
    child: Text("Hello",style: TextStyle(fontSize: 20.sp,))
)
  • Theme

    • Change theme

      MyTheme.changeTheme();
    • Check current theme

      bool isThemeLight = MyTheme.getThemeIsLight();
  • Localization

    • Change app locale

      LocalizationService.updateLanguage('en');
    • Get current locale

      LocalizationService.getCurrentLocal();
    • Use translation

      Text(Strings.hello.tr)

Discovering Project

After setting up all the needed thing now lets talk about folder structure which is mainly based on Getx Pattern and there are some personal opinions, if you open your lib folder you will find those folders

.
โ””โ”€โ”€ lib
    โ”œโ”€โ”€ app
    โ”‚   โ”œโ”€โ”€ components
    โ”‚   โ”œโ”€โ”€ data
    โ”‚   โ”‚   โ”œโ”€โ”€ local
    โ”‚   โ”‚   โ””โ”€โ”€ models
    โ”‚   โ”œโ”€โ”€ modules
    โ”‚   โ”‚   โ””โ”€โ”€ home
    โ”‚   โ”œโ”€โ”€ routes
    โ”‚   โ””โ”€โ”€ services
    โ”œโ”€โ”€ config
    โ”‚   โ”œโ”€โ”€ theme
    โ”‚   โ””โ”€โ”€ translation
    โ””โ”€โ”€ utils
  • app: will contain all our core app logic
    • components: will contain all the shared UI widgets
    • data: will contain our models and local data sources (local db & shared pref)
    • modules: app screens
    • routes: generated by get_cli and it will contain our navigation routes
    • services: contain all logic for making safe & clean api calls
  • config: will contain app config such as themes, localization services
  • utils: for our helper classes

Features

  • Theme: if you opened theme package you will see those files

    โ””โ”€โ”€ theme
        โ”œโ”€โ”€ dark_theme_colors.dart
        โ”œโ”€โ”€ light_theme_colors.dart
        โ”œโ”€โ”€ my_fonts.dart
        โ”œโ”€โ”€ my_styles.dart
        โ””โ”€โ”€ my_theme.dart
    
    

    you only need to change app colors (light/dark_theme_colors) and if you want to change app fonts sizes and family just modify my_fonts.dart and that is it you don't need to worry about styles and theme you only need to edit my_syles.dart if you want to change some element theme data (padding,border..etc) and if you want to change theme just use this code

    // change theme and save current theme state to shared pref
    MyTheme.changeTheme();

    and if you want to check if the theme is dark/light just use

    bool themeIsLight = MyTheme.getThemeIsLight();
    // OR
    bool themeIsLight = MySharedPref.getThemeIsLight();
  • Localization/translation we will use getx localization system which in the normal case code would look something like this

    class LocalizationService extends Translations {
        @override
        Map<String, Map<String, String>> get keys => {
            'en_US': { 'hello' : 'Hello' },
            'ar_AR': { 'hello' : 'ู…ุฑุญุจุงู‹' },
        };
    }
    
    Text('hello'.tr); // translated text 

    but because we have so many words to translate we will separate keys file (strings_enum.dart) and languages map into different classes so code will become like this

    class LocalizationService extends Translations {
          @override
          Map<String, Map<String, String>> get keys => {
              'en_US': enUs,
              'ar_AR': arAR,
          };
      }
    // keys
    class Strings {
        static const String hello = 'hello';
    }
    // english words
    const Map<String, String> enUs = {
        Strings.hello : 'Hello',
    }
    // arabic translate
    final Map<String, String> arAR = {
        Strings.hello : 'ู…ุฑุญุจุง',
    }
    //result
    Text(Strings.hello.tr)

    and that explain why we have this file structure inside our translation package

       โ””โ”€โ”€ translations
           โ”œโ”€โ”€ ar_Ar
           โ”‚   โ””โ”€โ”€ ar_ar_translation.dart
           โ”œโ”€โ”€ en_US
           โ”‚   โ””โ”€โ”€ en_us_translation.dart
           โ”œโ”€โ”€ localization_service.dart
           โ””โ”€โ”€ strings_enum.dart
    

    to change language you will use

    LocalizationService.updateLanguage('en');

    and to get the current locale/language you can use

    LocalizationService.getCurrentLocal();
    // OR
    MySharedPref.getCurrentLocal();

API CALLING

GET

  final awardList = RxList<AwardData>();

  getAwardList() async {
  showLoading('Loading award');

  var response = await DioClient().get(
          url: ApiUrl.allAward,
          header:  {
  "Authorization": "Bearer ${await MySharedPref.getToken()}"
  }).catchError(handleError);

  if (response == null) return;

  awardList.assignAll(
  (response["data"] as List).map((e) => AwardData.fromJson(e)).toList());

  hideLoading();
  }

POST

  createAward(int? employeeID, int? awardTypeID, String? date, String? gift,
      String? description) async {
    var request = {
      "employee_id": employeeID,
      "award_type": awardTypeID,
      "date": date,
      "gift": gift,
      "description": description,
    };
    showLoading('Creating award...');
    var response = await DioClient()
        .post(
          url:  ApiUrl.createHrAward,
            header: {"Authorization": "Bearer ${await MySharedPref.getToken()}"},
           body: request)
        .catchError(handleError);
    if (response == null) return;

  createAwardKey.currentState!.save();

  //reload();
  hideLoading();

  Get.back();
    await getAwardList();
  }

MULTIPART

  updateProfile([String? filePath]) async {
  var request = {
  "name": editNameController.text,
  "email": editMailController.text,
  };
  showLoading('Updating Profile...');
  var response = await DioClient()
  .multipartSingleFile(
  url: ApiUrl.updateProfile,
  header:  {
  "Authorization": "Bearer ${await MySharedPref.getToken()}",
  'Content-Type': 'multipart/form-data'
  },
 body: request,
 filepath: filePath,
 key: "profile")
  .catchError(handleError);
    if (response == null) return;

  profileEditKey.currentState!.save();
    //reload();
    await MySharedPref.removeUserAvatar();
    await MySharedPref.removeName();
    await MySharedPref.removeEmail();
    //
    await MySharedPref.setUserAvatar(response["data"]["profile"]);
    await MySharedPref.setName(editNameController.text);
    await MySharedPref.setEmail(editMailController.text);
    await MySharedPref.getUserAvatar();
    await MySharedPref.getName();
    await MySharedPref.getEmail();

  update();
  hideLoading();

  Get.back();
  }

}



Support

For support, email [email protected] or Facebook Mir Moktadir.

sleppy_medic's People

Contributors

mirmoktadir avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.