├── .gitignore
├── .metadata
├── LICENSE.md
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── thealteria
│ │ │ │ └── getx_start_project
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
└── images
│ └── ic_gallery.png
├── fonts
├── Nunito-Bold.ttf
├── Nunito-Regular.ttf
└── Nunito-SemiBold.ttf
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── app
│ ├── common
│ │ ├── constants.dart
│ │ ├── storage
│ │ │ └── storage.dart
│ │ ├── util
│ │ │ ├── exports.dart
│ │ │ ├── extensions.dart
│ │ │ ├── initializer.dart
│ │ │ ├── loading_dialog.dart
│ │ │ ├── utils.dart
│ │ │ └── validators.dart
│ │ └── values
│ │ │ ├── app_colors.dart
│ │ │ ├── app_images.dart
│ │ │ ├── strings.dart
│ │ │ └── styles
│ │ │ ├── app_text_style.dart
│ │ │ ├── dimens.dart
│ │ │ └── theme.dart
│ ├── data
│ │ ├── api_helper.dart
│ │ ├── api_helper_impl.dart
│ │ ├── api_response.dart
│ │ ├── errors
│ │ │ └── api_error.dart
│ │ └── interface_controller
│ │ │ └── api_interface_controller.dart
│ ├── modules
│ │ ├── home
│ │ │ ├── bindings
│ │ │ │ └── home_binding.dart
│ │ │ ├── controllers
│ │ │ │ └── home_controller.dart
│ │ │ └── views
│ │ │ │ └── home_view.dart
│ │ └── widgets
│ │ │ ├── base_widget.dart
│ │ │ ├── custom_appbar_widget.dart
│ │ │ ├── custom_back_button.dart
│ │ │ ├── custom_card_widget.dart
│ │ │ ├── custom_checkbox_widget.dart
│ │ │ ├── custom_drawer_header.dart
│ │ │ ├── custom_drawer_widget.dart
│ │ │ ├── custom_dropdown_textfield.dart
│ │ │ ├── custom_elevated_button.dart
│ │ │ ├── custom_error_widget.dart
│ │ │ ├── custom_image_widget.dart
│ │ │ ├── custom_inkwell_widget.dart
│ │ │ ├── custom_listtile_widget.dart
│ │ │ ├── custom_on_board_card_widget.dart
│ │ │ ├── custom_password_field.dart
│ │ │ ├── custom_retry_widget.dart
│ │ │ ├── custom_rich_text_widget.dart
│ │ │ ├── custom_row_text_widget.dart
│ │ │ ├── custom_text_button.dart
│ │ │ ├── custom_text_field_widget.dart
│ │ │ ├── on_boarding_base_widget.dart
│ │ │ └── stroke_background.dart
│ └── routes
│ │ ├── app_pages.dart
│ │ └── app_routes.dart
└── main.dart
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # Vscode related
20 | .classpath
21 | .project
22 | .settings/
23 | .vscode/
24 | *.code-workspace
25 | .history/
26 |
27 | # Flutter repo-specific
28 | /bin/cache/
29 | /bin/mingit/
30 | /dev/benchmarks/mega_gallery/
31 | /dev/bots/.recipe_deps
32 | /dev/bots/android_tools/
33 | /dev/docs/doc/
34 | /dev/docs/flutter.docs.zip
35 | /dev/docs/lib/
36 | /dev/docs/pubspec.yaml
37 | /dev/integration_tests/**/xcuserdata
38 | /dev/integration_tests/**/Pods
39 | /packages/flutter/coverage/
40 | version
41 |
42 | # packages file containing multi-root paths
43 | .packages.generated
44 |
45 | # Flutter/Dart/Pub related
46 | **/doc/api/
47 | **/ios/Flutter/.last_build_id
48 | .dart_tool/
49 | .flutter-plugins
50 | .flutter-plugins-dependencies
51 | .packages
52 | .pub-cache/
53 | .pub/
54 | /build/
55 | flutter_*.png
56 | linked_*.ds
57 | unlinked.ds
58 | unlinked_spec.ds
59 |
60 | # Web related
61 | lib/generated_plugin_registrant.dart
62 |
63 | # Symbolication related
64 | app.*.symbols
65 |
66 | # Obfuscation related
67 | app.*.map.json
68 |
69 | # Android related
70 | **/android/**/gradle-wrapper.jar
71 | **/android/.gradle
72 | **/android/captures/
73 | **/android/gradlew
74 | **/android/gradlew.bat
75 | **/android/local.properties
76 | **/android/**/GeneratedPluginRegistrant.java
77 | **/android/key.properties
78 | *.jks
79 |
80 | # iOS/XCode related
81 | **/ios/**/*.mode1v3
82 | **/ios/**/*.mode2v3
83 | **/ios/**/*.moved-aside
84 | **/ios/**/*.pbxuser
85 | **/ios/**/*.perspectivev3
86 | **/ios/**/*sync/
87 | **/ios/**/.sconsign.dblite
88 | **/ios/**/.tags*
89 | **/ios/**/.vagrant/
90 | **/ios/**/DerivedData/
91 | **/ios/**/Icon?
92 | **/ios/**/Pods/
93 | **/ios/**/.symlinks/
94 | **/ios/**/profile
95 | **/ios/**/xcuserdata
96 | **/ios/.generated/
97 | **/ios/Flutter/App.framework
98 | **/ios/Flutter/Flutter.framework
99 | **/ios/Flutter/Flutter.podspec
100 | **/ios/Flutter/Generated.xcconfig
101 | **/ios/Flutter/app.flx
102 | **/ios/Flutter/app.zip
103 | **/ios/Flutter/flutter_assets/
104 | **/ios/Flutter/flutter_export_environment.sh
105 | **/ios/ServiceDefinitions.json
106 | **/ios/Runner/GeneratedPluginRegistrant.*
107 |
108 | # macOS
109 | **/macos/Flutter/GeneratedPluginRegistrant.swift
110 | **/macos/Flutter/Flutter-Debug.xcconfig
111 | **/macos/Flutter/Flutter-Release.xcconfig
112 | **/macos/Flutter/Flutter-Profile.xcconfig
113 |
114 | # Coverage
115 | coverage/
116 |
117 | # Exceptions to above rules.
118 | !**/ios/**/default.mode1v3
119 | !**/ios/**/default.mode2v3
120 | !**/ios/**/default.pbxuser
121 | !**/ios/**/default.perspectivev3
122 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
123 | !/dev/ci/**/Gemfile.lock
124 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 78910062997c3a836feee883712c241a5fd22983
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Aman Gupta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GetX Boilerplate Template
2 |
3 | A boilerplate project created in flutter using GetX.
4 |
5 | ## Getting Started
6 |
7 | The boilerplate contains the minimal implementation required to create a new library or project. The repository code is preloaded with some basic components and utilities like basic app architecture, initializer, app theme, linting, constants, **api error handling** with proper errors display using `GetConnect` along with a `**retry button**` and storage using `get_storage`. Some 3rd party dependencies required to create a new project as per your preference. By using boilerplate code as standard initializer, we can have same patterns in all the projects that will inherit it if you're using GetX. This will also help in reducing setup & development time by allowing you to use same code pattern and avoid re-writing from scratch.
8 |
9 | ## How to Use
10 |
11 | **Step 1:**
12 |
13 | Download or clone this repo by using the link below:
14 |
15 | ```
16 | https://github.com/thealteria/flutter_getx_template.git
17 | ```
18 |
19 | Or simply click on the **Use this template** button and make your own repository using this template.
20 |
21 | **Step 2:**
22 |
23 | Go to project root and execute the following command in console to get the required dependencies:
24 |
25 | ```
26 | flutter pub get
27 | ```
28 |
29 | **NOTE**: Don't forget to change the 'app name' and 'package name' in android, ios, pubspec and strings files.
30 |
31 | ## Boilerplate Features:
32 |
33 | * Initializer - to intialize dependencies on startup
34 | * Home
35 | * Routing
36 | * Theme
37 | * Dynamic UI support
38 | * GetConnect with custom retry button and error handling
39 | * GetStorage
40 | * GetX (State Management and Naviagtion)
41 | * Custom Validations, widgets, dialogs, extensions and much more
42 |
43 | ### Libraries & Tools Used
44 |
45 | * [GetX](https://github.com/jonataslaw/getx)
46 | * [Storage](https://github.com/jonataslaw/get_storage)
47 | * [ScreenUtil](https://github.com/OpenFlutter/flutter_screenutil/)
48 | * [ImagePicker](https://github.com/flutter/plugins)
49 | * [ImageCropper](https://github.com/hnvn/flutter_image_cropper)
50 | * [ImagePicker](https://github.com/flutter/plugins)
51 | * [Intl](https://github.com/dart-lang/intl)
52 | * [OctoImage](https://github.com/Baseflow/octo_image)
53 |
54 | ### Folder Structure
55 | Here is the core folder structure which flutter provides.
56 |
57 | ```
58 | flutter-app/
59 | |- android
60 | |- build
61 | |- ios
62 | |- lib
63 | |- test
64 | ```
65 |
66 | Here is the folder structure we have been using in this project
67 |
68 | ```
69 | lib/
70 | |- app/
71 | |- main.dart
72 | ```
73 |
74 | ```
75 | app/
76 | |- common/
77 | |- storage/
78 | |- util/
79 | |- values/
80 | |- constants.dart
81 | |- data/
82 | |- errors/
83 | |- interface_controller/
84 | |- api_helper.dart
85 | |- app_response.dart
86 | |- modules/
87 | |- home/
88 | |- widgets/
89 | |- routes/
90 | ```
91 |
92 | Now, lets dive into the lib folder which has the main code for the application.
93 |
94 | ```
95 | 1- common - Contains all the utilities/common functions which are using throughout the app. This directory contains `constants`. `utilities`, `theme`, `strings`, `dimensions`, `storage`, `text styles`, `colors` and `images path`.
96 | 2- data - Contains the data layer of your project, includes a controller for retry apis, `custom errors` and response & error handling.
97 | 3- modules - Contains all the ui of your project, contains sub directory for each screen and custo widgets as per the need.
98 | 4- routes - Contains the files for routes for your application.
99 | 5- main.dart - This is the starting point of the application. All the application level configurations are defined in this file i.e, theme, routes, title, orientation etc.
100 | ```
101 | **NOTE**: You can use [Get Cli](https://github.com/jonataslaw/get_cli) to auto generate ui pages, controllers and routes.
102 |
103 | ## Conclusion
104 |
105 | This boilerplate template maybe seen over-architectured for what it is - but it is an example only. You can always customize it as per your preferences and need. All the issues/pull requests are welcome to make this boilerplate project more easy-to-use. If you liked it then don’t forget to ⭐ the repo to show your support🙂
106 |
107 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | analyzer:
13 | # strong-mode:
14 | # Will become the default once non-nullable types land
15 | # https://github.com/dart-lang/sdk/issues/31410#issuecomment-510683629
16 | # implicit-casts: false
17 |
18 | errors:
19 | missing_required_param: warning
20 | unnecessary_this: ignore
21 |
22 | constant_identifier_names: ignore
23 |
24 | linter:
25 | # The lint rules applied to this project can be customized in the
26 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
27 | # included above or to enable additional rules. A list of all available lints
28 | # and their documentation is published at
29 | # https://dart-lang.github.io/linter/lints/index.html.
30 | #
31 | # Instead of disabling a lint rule for the entire project in the
32 | # section below, it can also be suppressed for a single line of code
33 | # or a specific dart file by using the `// ignore: name_of_lint` and
34 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
35 | # producing the lint.
36 | rules:
37 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
38 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
39 | # Additional information about this file can be found at
40 | # https://dart.dev/guides/language/analysis-options
41 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 31
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.thealteria.flutter_getx_template"
42 | minSdkVersion 16
43 | targetSdkVersion 31
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
20 |
24 |
28 |
33 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/thealteria/getx_start_project/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.thealteria.flutter_getx_template
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.20'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.2.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/images/ic_gallery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/assets/images/ic_gallery.png
--------------------------------------------------------------------------------
/fonts/Nunito-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/fonts/Nunito-Bold.ttf
--------------------------------------------------------------------------------
/fonts/Nunito-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/fonts/Nunito-Regular.ttf
--------------------------------------------------------------------------------
/fonts/Nunito-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/fonts/Nunito-SemiBold.ttf
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXCopyFilesBuildPhase section */
19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 | isa = PBXCopyFilesBuildPhase;
21 | buildActionMask = 2147483647;
22 | dstPath = "";
23 | dstSubfolderSpec = 10;
24 | files = (
25 | );
26 | name = "Embed Frameworks";
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXCopyFilesBuildPhase section */
30 |
31 | /* Begin PBXFileReference section */
32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 9740EEB11CF90186004384FC /* Flutter */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 | );
66 | name = Flutter;
67 | sourceTree = "";
68 | };
69 | 97C146E51CF9000F007C117D = {
70 | isa = PBXGroup;
71 | children = (
72 | 9740EEB11CF90186004384FC /* Flutter */,
73 | 97C146F01CF9000F007C117D /* Runner */,
74 | 97C146EF1CF9000F007C117D /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | 97C146EF1CF9000F007C117D /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 97C146EE1CF9000F007C117D /* Runner.app */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | 97C146F01CF9000F007C117D /* Runner */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 | 97C147021CF9000F007C117D /* Info.plist */,
93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 | );
98 | path = Runner;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | 97C146ED1CF9000F007C117D /* Runner */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 | buildPhases = (
108 | 9740EEB61CF901F6004384FC /* Run Script */,
109 | 97C146EA1CF9000F007C117D /* Sources */,
110 | 97C146EB1CF9000F007C117D /* Frameworks */,
111 | 97C146EC1CF9000F007C117D /* Resources */,
112 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = Runner;
120 | productName = Runner;
121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 | productType = "com.apple.product-type.application";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 97C146E61CF9000F007C117D /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 1020;
131 | ORGANIZATIONNAME = "";
132 | TargetAttributes = {
133 | 97C146ED1CF9000F007C117D = {
134 | CreatedOnToolsVersion = 7.3.1;
135 | LastSwiftMigration = 1100;
136 | };
137 | };
138 | };
139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 | compatibilityVersion = "Xcode 9.3";
141 | developmentRegion = en;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | Base,
146 | );
147 | mainGroup = 97C146E51CF9000F007C117D;
148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 97C146ED1CF9000F007C117D /* Runner */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXResourcesBuildPhase section */
158 | 97C146EC1CF9000F007C117D /* Resources */ = {
159 | isa = PBXResourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXShellScriptBuildPhase section */
172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 | isa = PBXShellScriptBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | );
177 | inputPaths = (
178 | );
179 | name = "Thin Binary";
180 | outputPaths = (
181 | );
182 | runOnlyForDeploymentPostprocessing = 0;
183 | shellPath = /bin/sh;
184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
185 | };
186 | 9740EEB61CF901F6004384FC /* Run Script */ = {
187 | isa = PBXShellScriptBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | );
191 | inputPaths = (
192 | );
193 | name = "Run Script";
194 | outputPaths = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | shellPath = /bin/sh;
198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
199 | };
200 | /* End PBXShellScriptBuildPhase section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 97C146EA1CF9000F007C117D /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXSourcesBuildPhase section */
213 |
214 | /* Begin PBXVariantGroup section */
215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
216 | isa = PBXVariantGroup;
217 | children = (
218 | 97C146FB1CF9000F007C117D /* Base */,
219 | );
220 | name = Main.storyboard;
221 | sourceTree = "";
222 | };
223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
224 | isa = PBXVariantGroup;
225 | children = (
226 | 97C147001CF9000F007C117D /* Base */,
227 | );
228 | name = LaunchScreen.storyboard;
229 | sourceTree = "";
230 | };
231 | /* End PBXVariantGroup section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
240 | CLANG_CXX_LIBRARY = "libc++";
241 | CLANG_ENABLE_MODULES = YES;
242 | CLANG_ENABLE_OBJC_ARC = YES;
243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
244 | CLANG_WARN_BOOL_CONVERSION = YES;
245 | CLANG_WARN_COMMA = YES;
246 | CLANG_WARN_CONSTANT_CONVERSION = YES;
247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 | CLANG_WARN_EMPTY_BODY = YES;
250 | CLANG_WARN_ENUM_CONVERSION = YES;
251 | CLANG_WARN_INFINITE_RECURSION = YES;
252 | CLANG_WARN_INT_CONVERSION = YES;
253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 | CLANG_WARN_STRICT_PROTOTYPES = YES;
259 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 | CLANG_WARN_UNREACHABLE_CODE = YES;
261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
263 | COPY_PHASE_STRIP = NO;
264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 | ENABLE_NS_ASSERTIONS = NO;
266 | ENABLE_STRICT_OBJC_MSGSEND = YES;
267 | GCC_C_LANGUAGE_STANDARD = gnu99;
268 | GCC_NO_COMMON_BLOCKS = YES;
269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 | GCC_WARN_UNDECLARED_SELECTOR = YES;
272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 | GCC_WARN_UNUSED_FUNCTION = YES;
274 | GCC_WARN_UNUSED_VARIABLE = YES;
275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
276 | MTL_ENABLE_DEBUG_INFO = NO;
277 | SDKROOT = iphoneos;
278 | SUPPORTED_PLATFORMS = iphoneos;
279 | TARGETED_DEVICE_FAMILY = "1,2";
280 | VALIDATE_PRODUCT = YES;
281 | };
282 | name = Profile;
283 | };
284 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
285 | isa = XCBuildConfiguration;
286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
287 | buildSettings = {
288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
289 | CLANG_ENABLE_MODULES = YES;
290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
291 | ENABLE_BITCODE = NO;
292 | FRAMEWORK_SEARCH_PATHS = (
293 | "$(inherited)",
294 | "$(PROJECT_DIR)/Flutter",
295 | );
296 | INFOPLIST_FILE = Runner/Info.plist;
297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
298 | LIBRARY_SEARCH_PATHS = (
299 | "$(inherited)",
300 | "$(PROJECT_DIR)/Flutter",
301 | );
302 | PRODUCT_BUNDLE_IDENTIFIER = com.thealteria.getxStartProject;
303 | PRODUCT_NAME = "$(TARGET_NAME)";
304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
305 | SWIFT_VERSION = 5.0;
306 | VERSIONING_SYSTEM = "apple-generic";
307 | };
308 | name = Profile;
309 | };
310 | 97C147031CF9000F007C117D /* Debug */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | ALWAYS_SEARCH_USER_PATHS = NO;
314 | CLANG_ANALYZER_NONNULL = YES;
315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
316 | CLANG_CXX_LIBRARY = "libc++";
317 | CLANG_ENABLE_MODULES = YES;
318 | CLANG_ENABLE_OBJC_ARC = YES;
319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
320 | CLANG_WARN_BOOL_CONVERSION = YES;
321 | CLANG_WARN_COMMA = YES;
322 | CLANG_WARN_CONSTANT_CONVERSION = YES;
323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
325 | CLANG_WARN_EMPTY_BODY = YES;
326 | CLANG_WARN_ENUM_CONVERSION = YES;
327 | CLANG_WARN_INFINITE_RECURSION = YES;
328 | CLANG_WARN_INT_CONVERSION = YES;
329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
334 | CLANG_WARN_STRICT_PROTOTYPES = YES;
335 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
336 | CLANG_WARN_UNREACHABLE_CODE = YES;
337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
339 | COPY_PHASE_STRIP = NO;
340 | DEBUG_INFORMATION_FORMAT = dwarf;
341 | ENABLE_STRICT_OBJC_MSGSEND = YES;
342 | ENABLE_TESTABILITY = YES;
343 | GCC_C_LANGUAGE_STANDARD = gnu99;
344 | GCC_DYNAMIC_NO_PIC = NO;
345 | GCC_NO_COMMON_BLOCKS = YES;
346 | GCC_OPTIMIZATION_LEVEL = 0;
347 | GCC_PREPROCESSOR_DEFINITIONS = (
348 | "DEBUG=1",
349 | "$(inherited)",
350 | );
351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
353 | GCC_WARN_UNDECLARED_SELECTOR = YES;
354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
355 | GCC_WARN_UNUSED_FUNCTION = YES;
356 | GCC_WARN_UNUSED_VARIABLE = YES;
357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
358 | MTL_ENABLE_DEBUG_INFO = YES;
359 | ONLY_ACTIVE_ARCH = YES;
360 | SDKROOT = iphoneos;
361 | TARGETED_DEVICE_FAMILY = "1,2";
362 | };
363 | name = Debug;
364 | };
365 | 97C147041CF9000F007C117D /* Release */ = {
366 | isa = XCBuildConfiguration;
367 | buildSettings = {
368 | ALWAYS_SEARCH_USER_PATHS = NO;
369 | CLANG_ANALYZER_NONNULL = YES;
370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
371 | CLANG_CXX_LIBRARY = "libc++";
372 | CLANG_ENABLE_MODULES = YES;
373 | CLANG_ENABLE_OBJC_ARC = YES;
374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
375 | CLANG_WARN_BOOL_CONVERSION = YES;
376 | CLANG_WARN_COMMA = YES;
377 | CLANG_WARN_CONSTANT_CONVERSION = YES;
378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
380 | CLANG_WARN_EMPTY_BODY = YES;
381 | CLANG_WARN_ENUM_CONVERSION = YES;
382 | CLANG_WARN_INFINITE_RECURSION = YES;
383 | CLANG_WARN_INT_CONVERSION = YES;
384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
389 | CLANG_WARN_STRICT_PROTOTYPES = YES;
390 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
391 | CLANG_WARN_UNREACHABLE_CODE = YES;
392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
394 | COPY_PHASE_STRIP = NO;
395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
396 | ENABLE_NS_ASSERTIONS = NO;
397 | ENABLE_STRICT_OBJC_MSGSEND = YES;
398 | GCC_C_LANGUAGE_STANDARD = gnu99;
399 | GCC_NO_COMMON_BLOCKS = YES;
400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
402 | GCC_WARN_UNDECLARED_SELECTOR = YES;
403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
404 | GCC_WARN_UNUSED_FUNCTION = YES;
405 | GCC_WARN_UNUSED_VARIABLE = YES;
406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
407 | MTL_ENABLE_DEBUG_INFO = NO;
408 | SDKROOT = iphoneos;
409 | SUPPORTED_PLATFORMS = iphoneos;
410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
411 | TARGETED_DEVICE_FAMILY = "1,2";
412 | VALIDATE_PRODUCT = YES;
413 | };
414 | name = Release;
415 | };
416 | 97C147061CF9000F007C117D /* Debug */ = {
417 | isa = XCBuildConfiguration;
418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
419 | buildSettings = {
420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
421 | CLANG_ENABLE_MODULES = YES;
422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
423 | ENABLE_BITCODE = NO;
424 | FRAMEWORK_SEARCH_PATHS = (
425 | "$(inherited)",
426 | "$(PROJECT_DIR)/Flutter",
427 | );
428 | INFOPLIST_FILE = Runner/Info.plist;
429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
430 | LIBRARY_SEARCH_PATHS = (
431 | "$(inherited)",
432 | "$(PROJECT_DIR)/Flutter",
433 | );
434 | PRODUCT_BUNDLE_IDENTIFIER = com.thealteria.getxStartProject;
435 | PRODUCT_NAME = "$(TARGET_NAME)";
436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
438 | SWIFT_VERSION = 5.0;
439 | VERSIONING_SYSTEM = "apple-generic";
440 | };
441 | name = Debug;
442 | };
443 | 97C147071CF9000F007C117D /* Release */ = {
444 | isa = XCBuildConfiguration;
445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
446 | buildSettings = {
447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
448 | CLANG_ENABLE_MODULES = YES;
449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
450 | ENABLE_BITCODE = NO;
451 | FRAMEWORK_SEARCH_PATHS = (
452 | "$(inherited)",
453 | "$(PROJECT_DIR)/Flutter",
454 | );
455 | INFOPLIST_FILE = Runner/Info.plist;
456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
457 | LIBRARY_SEARCH_PATHS = (
458 | "$(inherited)",
459 | "$(PROJECT_DIR)/Flutter",
460 | );
461 | PRODUCT_BUNDLE_IDENTIFIER = com.thealteria.getxStartProject;
462 | PRODUCT_NAME = "$(TARGET_NAME)";
463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
464 | SWIFT_VERSION = 5.0;
465 | VERSIONING_SYSTEM = "apple-generic";
466 | };
467 | name = Release;
468 | };
469 | /* End XCBuildConfiguration section */
470 |
471 | /* Begin XCConfigurationList section */
472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
473 | isa = XCConfigurationList;
474 | buildConfigurations = (
475 | 97C147031CF9000F007C117D /* Debug */,
476 | 97C147041CF9000F007C117D /* Release */,
477 | 249021D3217E4FDB00AE95B9 /* Profile */,
478 | );
479 | defaultConfigurationIsVisible = 0;
480 | defaultConfigurationName = Release;
481 | };
482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
483 | isa = XCConfigurationList;
484 | buildConfigurations = (
485 | 97C147061CF9000F007C117D /* Debug */,
486 | 97C147071CF9000F007C117D /* Release */,
487 | 249021D4217E4FDB00AE95B9 /* Profile */,
488 | );
489 | defaultConfigurationIsVisible = 0;
490 | defaultConfigurationName = Release;
491 | };
492 | /* End XCConfigurationList section */
493 | };
494 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
495 | }
496 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thealteria/flutter_getx_template/781c8ade7b218a1c248839e427366003f7f5f2bd/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_getx_template
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/app/common/constants.dart:
--------------------------------------------------------------------------------
1 | abstract class Constants {
2 | static const String baseUrl = String.fromEnvironment('B');
3 |
4 | static const timeout = Duration(seconds: 5);
5 | static const String token = 'authToken';
6 |
7 | static const String dummyImageUrl =
8 | 'https://i.picsum.photos/id/1084/536/354.jpg'
9 | '?grayscale&hmac=Ux7nzg19e1q35mlUVZjhCLxqkR30cC-CarVg-nlIf60';
10 | static const String placeHolderBlurHash = 'LEHV6nWB2yk8pyo0adR*.7kCMdnj';
11 | }
12 |
--------------------------------------------------------------------------------
/lib/app/common/storage/storage.dart:
--------------------------------------------------------------------------------
1 | import 'package:get_storage/get_storage.dart';
2 |
3 | abstract class Storage {
4 | static final GetStorage _storage = GetStorage();
5 |
6 | static GetStorage get storage => _storage;
7 |
8 | static Future saveValue(String key, dynamic value) =>
9 | _storage.writeIfNull(key, value);
10 |
11 | static T? getValue(String key) => _storage.read(key);
12 |
13 | static bool hasData(String key) => _storage.hasData(key);
14 |
15 | static Future removeValue(String key) => _storage.remove(key);
16 |
17 | static Future clearStorage() => _storage.erase();
18 | }
19 |
--------------------------------------------------------------------------------
/lib/app/common/util/exports.dart:
--------------------------------------------------------------------------------
1 | library exports;
2 |
3 | export 'package:flutter_getx_template/app/common/storage/storage.dart';
4 | export 'package:flutter_getx_template/app/common/util/extensions.dart';
5 | export 'package:flutter_getx_template/app/common/util/utils.dart';
6 | export 'package:flutter_getx_template/app/common/values/app_colors.dart';
7 | export 'package:flutter_getx_template/app/common/values/app_images.dart';
8 | export 'package:flutter_getx_template/app/common/values/strings.dart';
9 | export 'package:flutter_getx_template/app/common/values/styles/app_text_style.dart';
10 | export 'package:flutter_getx_template/app/common/values/styles/dimens.dart';
11 | export 'package:flutter_getx_template/app/common/values/styles/theme.dart';
12 | export 'package:flutter_screenutil/flutter_screenutil.dart';
13 |
--------------------------------------------------------------------------------
/lib/app/common/util/extensions.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/constants.dart';
3 | import 'package:flutter_getx_template/app/common/util/exports.dart';
4 | import 'package:flutter_getx_template/app/data/api_response.dart';
5 | import 'package:flutter_getx_template/app/data/errors/api_error.dart';
6 | import 'package:flutter_getx_template/app/data/interface_controller/api_interface_controller.dart';
7 | import 'package:flutter_getx_template/app/routes/app_pages.dart';
8 | import 'package:get/get.dart';
9 | import 'package:intl/intl.dart';
10 |
11 | import 'loading_dialog.dart';
12 |
13 | abstract class Extensions {}
14 |
15 | extension BorderRadiusExt on num {
16 | BorderRadius get borderRadius => BorderRadius.circular(this.r);
17 |
18 | InputBorder outlineInputBorder({
19 | BorderSide borderSide = BorderSide.none,
20 | }) =>
21 | OutlineInputBorder(
22 | borderRadius: this.borderRadius,
23 | borderSide: borderSide,
24 | );
25 |
26 | BorderSide borderSide({
27 | Color? color,
28 | double? width,
29 | BorderStyle? style,
30 | }) =>
31 | BorderSide(
32 | color: color ?? Colors.white,
33 | width: this.toDouble(),
34 | style: style ?? BorderStyle.solid,
35 | );
36 | }
37 |
38 | extension HexColorExt on String {
39 | Color get fromHex {
40 | final buffer = StringBuffer();
41 | if (this.length == 6 || this.length == 7) {
42 | buffer.write('ff');
43 | }
44 |
45 | if (this.startsWith('#')) {
46 | buffer.write(this.replaceFirst('#', ''));
47 | }
48 | return Color(int.parse(buffer.toString(), radix: 16));
49 | }
50 | }
51 |
52 | extension DateTimeFormatterExt on DateTime {
53 | String formatedDate({
54 | String dateFormat = 'yyyy-MM-dd',
55 | }) {
56 | final formatter = DateFormat(dateFormat);
57 | return formatter.format(this);
58 | }
59 | }
60 |
61 | extension TimeOfDayExt on String {
62 | TimeOfDay getTimeOfDay({
63 | int addMinutes = 0,
64 | }) =>
65 | TimeOfDay.fromDateTime(
66 | DateFormat.jm().parse(this).add(
67 | Duration(
68 | minutes: addMinutes,
69 | ),
70 | ),
71 | );
72 | }
73 |
74 | extension ImageExt on String {
75 | String get image => 'assets/images/$this.png';
76 |
77 | Image imageAsset({
78 | Size? size,
79 | BoxFit? fit,
80 | Color? color,
81 | }) =>
82 | Image.asset(
83 | this,
84 | color: color,
85 | width: size?.width,
86 | height: size?.height,
87 | fit: fit,
88 | );
89 | }
90 |
91 | extension FutureExt on Future?> {
92 | void futureValue(
93 | Function(T value) response, {
94 | Function(String? error)? onError,
95 | required VoidCallback retryFunction,
96 | bool showLoading = true,
97 | }) {
98 | final _interface = Get.find();
99 | _interface.error = null;
100 |
101 | if (showLoading) LoadingDialog.showLoadingDialog();
102 |
103 | this.timeout(
104 | Constants.timeout,
105 | onTimeout: () {
106 | LoadingDialog.closeLoadingDialog();
107 |
108 | Utils.showSnackbar(Strings.connectionTimeout);
109 |
110 | _retry(_interface, retryFunction);
111 |
112 | throw const ApiError(
113 | type: ErrorType.connectTimeout,
114 | error: Strings.connectionTimeout,
115 | );
116 | },
117 | ).then((value) {
118 | LoadingDialog.closeLoadingDialog();
119 |
120 | if (value?.body != null) {
121 | final result = ApiResponse.getResponse(value!);
122 | if (result != null) {
123 | response(result);
124 | }
125 | }
126 |
127 | _interface.update();
128 | }).catchError((e) {
129 | LoadingDialog.closeLoadingDialog();
130 |
131 | if (e == null) return;
132 |
133 | final String errorMessage = e is ApiError ? e.message : e.toString();
134 |
135 | if (e is ApiError) {
136 | if ((e.type == ErrorType.connectTimeout ||
137 | e.type == ErrorType.noConnection)) {
138 | _interface.error = e;
139 |
140 | _retry(_interface, retryFunction);
141 | } else {
142 | Utils.showDialog(
143 | errorMessage,
144 | onTap: errorMessage != Strings.unauthorize
145 | ? null
146 | : () {
147 | Storage.clearStorage();
148 | Get.offAllNamed(
149 | Routes.HOME,
150 | //change the ROUTE to the LOGIN or SPLASH screen so that the
151 | //user can login again on UnauthorizeError error
152 | );
153 | },
154 | );
155 | }
156 | }
157 |
158 | if (onError != null) {
159 | onError(errorMessage);
160 | }
161 |
162 | printError(info: 'catchError: error: $e\nerrorMessage: $errorMessage');
163 | });
164 | }
165 |
166 | void _retry(
167 | ApiInterfaceController _interface,
168 | VoidCallback retryFunction,
169 | ) {
170 | _interface.retry = retryFunction;
171 | _interface.update();
172 | }
173 | }
174 |
175 | extension AlignWidgetExt on Widget {
176 | Widget align({
177 | Alignment alignment = Alignment.center,
178 | }) =>
179 | Align(
180 | alignment: alignment,
181 | child: this,
182 | );
183 | }
184 |
185 | extension FormatDurationExt on int {
186 | String formatDuration() {
187 | final min = this ~/ 60;
188 | final sec = this % 60;
189 | return "${min.toString().padLeft(2, "0")}:${sec.toString().padLeft(2, "0")} min";
190 | }
191 | }
192 |
193 | extension DebugLog on String {
194 | void debugLog() {
195 | return debugPrint(
196 | '\n******************************* DebugLog *******************************\n'
197 | ' $this'
198 | '\n******************************* DebugLog *******************************\n',
199 | wrapWidth: 1024,
200 | );
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/lib/app/common/util/initializer.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/services.dart';
4 | import 'package:flutter/widgets.dart';
5 | import 'package:flutter_getx_template/app/data/api_helper.dart';
6 | import 'package:flutter_getx_template/app/data/api_helper_impl.dart';
7 | import 'package:flutter_getx_template/app/data/interface_controller/api_interface_controller.dart';
8 | import 'package:flutter_getx_template/app/modules/widgets/custom_error_widget.dart';
9 | import 'package:get/get.dart';
10 | import 'package:get_storage/get_storage.dart';
11 |
12 | abstract class Initializer {
13 | static void init(VoidCallback runApp) {
14 | ErrorWidget.builder = (errorDetails) {
15 | return CustomErrorWidget(
16 | message: errorDetails.exceptionAsString(),
17 | );
18 | };
19 |
20 | runZonedGuarded(() async {
21 | WidgetsFlutterBinding.ensureInitialized();
22 | FlutterError.onError = (details) {
23 | FlutterError.dumpErrorToConsole(details);
24 | Get.printInfo(info: details.stack.toString());
25 | };
26 |
27 | await _initServices();
28 | runApp();
29 | }, (error, stack) {
30 | Get.printInfo(info: 'runZonedGuarded: ${error.toString()}');
31 | });
32 | }
33 |
34 | static Future _initServices() async {
35 | try {
36 | await _initStorage();
37 |
38 | _initScreenPreference();
39 | } catch (err) {
40 | rethrow;
41 | }
42 | }
43 |
44 | static Future _initStorage() async {
45 | await GetStorage.init();
46 | }
47 |
48 | static void _initScreenPreference() {
49 | SystemChrome.setPreferredOrientations([
50 | DeviceOrientation.portraitUp,
51 | DeviceOrientation.portraitDown,
52 | ]);
53 | }
54 | }
55 |
56 | class InitialBindings extends Bindings {
57 | @override
58 | void dependencies() {
59 | Get.lazyPut(
60 | () => ApiHelperImpl(),
61 | );
62 |
63 | Get.lazyPut(
64 | () => ApiInterfaceController(),
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/lib/app/common/util/loading_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_getx_template/app/common/util/utils.dart';
2 | import 'package:get/get.dart';
3 |
4 | typedef CloseDialog = void Function();
5 |
6 | abstract class LoadingDialog {
7 | static CloseDialog? _loadingDialog;
8 |
9 | static CloseDialog _showLoadingDialog() {
10 | Get.printInfo(info: 'initialized loading');
11 | Utils.loadingDialog();
12 | return Utils.closeDialog;
13 | }
14 |
15 | static void showLoadingDialog() {
16 | _loadingDialog = _showLoadingDialog();
17 | Get.printInfo(info: 'start loading');
18 | }
19 |
20 | static void closeLoadingDialog() {
21 | Get.printInfo(info: 'close loading');
22 | _loadingDialog?.call();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/app/common/util/utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:math';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter_getx_template/app/common/util/exports.dart';
6 | import 'package:flutter_getx_template/app/modules/widgets/custom_inkwell_widget.dart';
7 | import 'package:flutter_getx_template/app/modules/widgets/custom_text_button.dart';
8 | import 'package:get/get.dart';
9 | import 'package:image_cropper/image_cropper.dart';
10 | import 'package:image_picker/image_picker.dart';
11 |
12 | abstract class Utils {
13 | static void showDialog(
14 | String? message, {
15 | String title = Strings.error,
16 | bool success = false,
17 | VoidCallback? onTap,
18 | }) =>
19 | Get.defaultDialog(
20 | barrierDismissible: false,
21 | onWillPop: () async {
22 | Get.back();
23 |
24 | onTap?.call();
25 |
26 | return true;
27 | },
28 | title: success ? Strings.success : title,
29 | content: Text(
30 | message ?? Strings.somethingWentWrong,
31 | textAlign: TextAlign.center,
32 | maxLines: 6,
33 | style: AppTextStyle.semiBoldStyle.copyWith(
34 | color: AppColors.mineShaft,
35 | fontSize: Dimens.fontSize16,
36 | ),
37 | ),
38 | confirm: Align(
39 | alignment: Alignment.centerRight,
40 | child: CustomInkwellWidget.text(
41 | onTap: () {
42 | Get.back();
43 |
44 | onTap?.call();
45 | },
46 | title: Strings.ok,
47 | textStyle: AppTextStyle.buttonTextStyle.copyWith(
48 | fontSize: Dimens.fontSize18,
49 | ),
50 | ),
51 | ),
52 | );
53 |
54 | static void showIconDialog(
55 | String title,
56 | String message, {
57 | Widget? imageWidget,
58 | VoidCallback? onTap,
59 | }) =>
60 | Get.dialog(
61 | AlertDialog(
62 | title:
63 | imageWidget ?? const Icon(Icons.done), //add your icon/image here
64 | content: Column(
65 | mainAxisSize: MainAxisSize.min,
66 | children: [
67 | Text(
68 | title,
69 | textAlign: TextAlign.center,
70 | style: AppTextStyle.semiBoldStyle.copyWith(
71 | color: Colors.black,
72 | fontSize: Dimens.fontSize24,
73 | ),
74 | ),
75 | SizedBox(height: 10.w),
76 | Text(message,
77 | textAlign: TextAlign.center,
78 | style: AppTextStyle.regularStyle.copyWith(
79 | color: AppColors.mineShaft,
80 | fontSize: Dimens.fontSize16,
81 | )),
82 | SizedBox(height: 20.w),
83 | CustomTextButton(
84 | title: Strings.ok,
85 | onPressed: () {
86 | Get.back();
87 |
88 | onTap?.call();
89 | },
90 | ),
91 | ],
92 | ),
93 | ),
94 | barrierDismissible: false,
95 | );
96 |
97 | static void timePicker(
98 | Function(String time) onSelectTime, {
99 | TimeOfDay? initialTime,
100 | }) {
101 | showTimePicker(
102 | context: Get.overlayContext!,
103 | initialTime: initialTime ??
104 | TimeOfDay.fromDateTime(
105 | DateTime.now(),
106 | ),
107 | ).then((v) {
108 | if (v != null) {
109 | final _now = DateTime.now();
110 | final _dateTime = DateTime(
111 | _now.year,
112 | _now.month,
113 | _now.day,
114 | v.hour,
115 | v.minute,
116 | );
117 |
118 | onSelectTime(_dateTime.formatedDate(dateFormat: 'hh:mm aa'));
119 | }
120 | });
121 | }
122 |
123 | static String getRandomString(
124 | int length, {
125 | bool isNumber = true,
126 | }) {
127 | final _chars = isNumber ? '1234567890' : 'abcdefghijklmnopqrstuvwxyz';
128 | final _rnd = Random();
129 |
130 | return String.fromCharCodes(
131 | Iterable.generate(
132 | length,
133 | (_) => _chars.codeUnitAt(
134 | _rnd.nextInt(
135 | _chars.length,
136 | ),
137 | ),
138 | ),
139 | );
140 | }
141 |
142 | static void loadingDialog() {
143 | closeDialog();
144 |
145 | Get.dialog(
146 | const Center(
147 | child: CircularProgressIndicator(),
148 | ),
149 | name: 'loadingDialog',
150 | );
151 | }
152 |
153 | static void closeDialog() {
154 | if (Get.isDialogOpen == true) {
155 | Get.back();
156 | }
157 | }
158 |
159 | static void closeSnackbar() {
160 | if (Get.isSnackbarOpen == true) {
161 | Get.back();
162 | }
163 | }
164 |
165 | static void showSnackbar(String? message) {
166 | closeSnackbar();
167 |
168 | Get.rawSnackbar(message: message);
169 | }
170 |
171 | static void closeKeyboard() {
172 | final currentFocus = Get.focusScope!;
173 | if (!currentFocus.hasPrimaryFocus) {
174 | currentFocus.unfocus();
175 | }
176 | }
177 |
178 | static void goBackToScreen(String routeName) {
179 | Get.until(
180 | (route) => route.settings.name == routeName,
181 | );
182 | }
183 |
184 | static Future showImagePicker({
185 | required Function(File image) onGetImage,
186 | }) {
187 | return showModalBottomSheet(
188 | context: Get.context!,
189 | builder: (_) {
190 | return Padding(
191 | padding: EdgeInsets.all(10.w),
192 | child: Row(
193 | mainAxisSize: MainAxisSize.min,
194 | mainAxisAlignment: MainAxisAlignment.center,
195 | children: [
196 | Expanded(
197 | child: InkWell(
198 | onTap: () {
199 | getImage(source: 2).then((v) {
200 | if (v != null) {
201 | onGetImage(v);
202 | Get.back();
203 | }
204 | });
205 | },
206 | child: Column(
207 | mainAxisSize: MainAxisSize.min,
208 | children: [
209 | Icon(
210 | Icons.image,
211 | size: 60.w,
212 | ),
213 | SizedBox(height: 10.h),
214 | Text(
215 | Strings.gallery,
216 | textAlign: TextAlign.center,
217 | style: AppTextStyle.semiBoldStyle.copyWith(
218 | color: AppColors.mineShaft,
219 | fontSize: Dimens.fontSize16,
220 | ),
221 | )
222 | ],
223 | ),
224 | ),
225 | ),
226 | Expanded(
227 | child: InkWell(
228 | onTap: () {
229 | getImage().then((v) {
230 | if (v != null) {
231 | onGetImage(v);
232 | Get.back();
233 | }
234 | });
235 | },
236 | child: Column(
237 | mainAxisSize: MainAxisSize.min,
238 | children: [
239 | Icon(
240 | Icons.camera,
241 | size: 60.w,
242 | ),
243 | SizedBox(
244 | height: 10.h,
245 | ),
246 | Text(
247 | Strings.camera,
248 | textAlign: TextAlign.center,
249 | style: AppTextStyle.semiBoldStyle.copyWith(
250 | color: AppColors.mineShaft,
251 | fontSize: Dimens.fontSize16,
252 | ),
253 | )
254 | ],
255 | ),
256 | ),
257 | )
258 | ],
259 | ),
260 | );
261 | },
262 | );
263 | }
264 |
265 | static Future getImage({int source = 1}) async {
266 | File? croppedFile;
267 | final picker = ImagePicker();
268 |
269 | final pickedFile = await picker.pickImage(
270 | source: source == 1 ? ImageSource.camera : ImageSource.gallery,
271 | imageQuality: 60,
272 | );
273 |
274 | if (pickedFile != null) {
275 | final image = File(pickedFile.path);
276 |
277 | croppedFile = await ImageCropper().cropImage(
278 | compressQuality: 50,
279 | sourcePath: image.path,
280 | aspectRatioPresets: [
281 | CropAspectRatioPreset.square,
282 | CropAspectRatioPreset.ratio3x2,
283 | CropAspectRatioPreset.original,
284 | CropAspectRatioPreset.ratio4x3,
285 | CropAspectRatioPreset.ratio16x9
286 | ],
287 | androidUiSettings: const AndroidUiSettings(
288 | toolbarColor: Colors.transparent,
289 | toolbarWidgetColor: Colors.transparent,
290 | initAspectRatio: CropAspectRatioPreset.original,
291 | lockAspectRatio: false,
292 | ),
293 | iosUiSettings: const IOSUiSettings(
294 | minimumAspectRatio: 0.1,
295 | aspectRatioLockDimensionSwapEnabled: true,
296 | ),
297 | );
298 | }
299 |
300 | return croppedFile;
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/lib/app/common/util/validators.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_getx_template/app/common/util/exports.dart';
2 | import 'package:get/get.dart';
3 |
4 | abstract class Validators {
5 | static String? validateEmpty(String? v) {
6 | if (v!.isEmpty) {
7 | return Strings.fieldCantBeEmpty;
8 | } else {
9 | return null;
10 | }
11 | }
12 |
13 | static String? validateTEmpty(T? v) {
14 | if (v == null) {
15 | return Strings.fieldCantBeEmpty;
16 | } else {
17 | return null;
18 | }
19 | }
20 |
21 | static String? validateEmail(String? v) {
22 | if (v!.isEmpty) {
23 | return Strings.emailCantBeEmpty;
24 | } else if (!GetUtils.isEmail(v)) {
25 | return Strings.enterValidEmail;
26 | } else {
27 | return null;
28 | }
29 | }
30 |
31 | static String? validatePhone(String? v) {
32 | if (v!.isEmpty) {
33 | return Strings.fieldCantBeEmpty;
34 | } else if (v.length != 10) {
35 | return Strings.enterValidNumber;
36 | } else {
37 | return null;
38 | }
39 | }
40 |
41 | static String? validateEmailPhone(String? v) {
42 | if (v!.isEmpty) {
43 | return Strings.fieldCantBeEmpty;
44 | } else if (GetUtils.isNumericOnly(v)) {
45 | return validatePhone(v);
46 | } else {
47 | return validateEmail(v);
48 | }
49 | }
50 |
51 | static String? validatePassword(String? v) {
52 | if (v!.isEmpty) {
53 | return Strings.passwordCantBeEmpty;
54 | } else if (v.length < 8) {
55 | return Strings.passwordValidation;
56 | } else {
57 | return null;
58 | }
59 | }
60 |
61 | static String? validateConfirmPassword(String? v, String password) {
62 | if (v!.isEmpty || password.isEmpty) {
63 | return Strings.passwordCantBeEmpty;
64 | } else if (v.length < 8 || password.length < 8 || v != password) {
65 | return Strings.confirmPasswordValidation;
66 | } else {
67 | return null;
68 | }
69 | }
70 |
71 | static String? validateCheckbox({
72 | bool v = false,
73 | String error = Strings.checkboxValidation,
74 | }) {
75 | if (!v) {
76 | return error;
77 | } else {
78 | return null;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/app/common/values/app_colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | abstract class AppColors {
4 | static const Color kPrimaryColor = Color(0xFF1976D2);
5 | static const Color mineShaft = Color(0xFF2B2B2B);
6 | static const Color doveGray = Color(0xFF646464);
7 | static const Color caribbeanGreen = Color(0xFF06C5AC);
8 | static const Color amaranth = Color(0xFFea435d);
9 | static const Color black = Colors.black;
10 | static const Color white = Colors.white;
11 | }
12 |
--------------------------------------------------------------------------------
/lib/app/common/values/app_images.dart:
--------------------------------------------------------------------------------
1 | abstract class AppImages {
2 | ///add app images here
3 |
4 | static const String icGallery = 'assets/images/ic_gallery.png';
5 | }
6 |
--------------------------------------------------------------------------------
/lib/app/common/values/strings.dart:
--------------------------------------------------------------------------------
1 | abstract class Strings {
2 | static const unknownError = 'Unknow error! Please try again after some time.';
3 | static const connectionTimeout =
4 | 'Connection timeout. Please try again after some time.';
5 | static const noConnection = 'No connection. Please turn on your internet!';
6 | static const unauthorize = 'Unauthorize. Please login again!';
7 |
8 | static const String appName = 'Getx Template';
9 | static const String ok = 'Ok';
10 | static const String error = 'Error';
11 | static const String noInternet = 'No internet. Please try again later.';
12 | static const String logOut = 'Log out';
13 | static const String retry = 'Retry';
14 | static const String somethingWentWrong = 'Something went wrong.';
15 | static const String home = 'Home';
16 | static const emailAddress = 'Email Address';
17 | static const mobileNumber = 'Mobile Number';
18 | static const String emailOrMobile = '$emailAddress or $mobileNumber';
19 | static const String cantBeEmpty = "can't be empty.";
20 | static const String fieldCantBeEmpty = 'Field $cantBeEmpty';
21 | static const String numberCantBeEmpty = '$emailOrMobile $cantBeEmpty';
22 | static const String emailCantBeEmpty = 'Email $cantBeEmpty';
23 | static const String enterValid = 'Please enter a valid';
24 | static const String enterValidNumber = '$enterValid $mobileNumber.';
25 | static const String enterValidEmail = '$enterValid email.';
26 | static const String password = 'Password';
27 | static const String confirmPassword = 'Confirm $password';
28 | static const String enterPassword = 'Enter $password';
29 | static const String passwordCantBeEmpty = '$password $cantBeEmpty';
30 | static const String passwordValidation =
31 | '$password must be at least 8 characters long.';
32 | static const confirmPasswordValidation =
33 | '$password and Confirm password should be same.';
34 | static const otpValidation = 'Invalid OTP';
35 | static const gallery = 'Gallery';
36 | static const camera = 'Camera';
37 | static const mobile = 'Mobile';
38 | static const from = 'From';
39 | static const to = 'To';
40 | static const success = 'Success';
41 | static const checkboxValidation = 'Dummy Checkbox Validation Message';
42 | }
43 |
--------------------------------------------------------------------------------
/lib/app/common/values/styles/app_text_style.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'dimens.dart';
4 |
5 | abstract class AppTextStyle {
6 | /// NAME SIZE WEIGHT SPACING
7 | /// headline1 96.0 light -1.5
8 | static final TextStyle headline1 = lightStyle.copyWith(
9 | fontSize: Dimens.fontSize96,
10 | letterSpacing: -1.5,
11 | );
12 |
13 | /// NAME SIZE WEIGHT SPACING
14 | /// headline2 60.0 light -0.5
15 | static final TextStyle headline2 = lightStyle.copyWith(
16 | fontSize: Dimens.fontSize60,
17 | letterSpacing: -0.5,
18 | );
19 |
20 | /// NAME SIZE WEIGHT SPACING
21 | /// headline3 48.0 regular 0.0
22 | static final TextStyle headline3 = regularStyle.copyWith(
23 | fontSize: Dimens.fontSize48,
24 | letterSpacing: 0,
25 | );
26 |
27 | /// NAME SIZE WEIGHT SPACING
28 | /// headline4 34.0 regular 0.25
29 | static final TextStyle headline4 = regularStyle.copyWith(
30 | fontSize: Dimens.fontSize34,
31 | letterSpacing: 0.25,
32 | );
33 |
34 | /// NAME SIZE WEIGHT SPACING
35 | /// headline5 24.0 regular 0.0
36 | static final TextStyle headline5 = regularStyle.copyWith(
37 | fontSize: Dimens.fontSize24,
38 | letterSpacing: 0,
39 | );
40 |
41 | /// NAME SIZE WEIGHT SPACING
42 | /// headline6 20.0 medium 0.15
43 | static final TextStyle headline6 = mediumStyle.copyWith(
44 | fontSize: Dimens.fontSize20,
45 | letterSpacing: 0.15,
46 | );
47 |
48 | /// NAME SIZE WEIGHT SPACING
49 | /// subtitle1 16.0 regular 0.15
50 | static final TextStyle subtitle1 = regularStyle.copyWith(
51 | fontSize: Dimens.fontSize16,
52 | letterSpacing: 0.15,
53 | );
54 |
55 | /// NAME SIZE WEIGHT SPACING
56 | /// subtitle2 14.0 medium 0.1
57 | static final TextStyle subtitle2 = mediumStyle.copyWith(
58 | fontSize: Dimens.fontSize14,
59 | letterSpacing: 0.1,
60 | );
61 |
62 | /// NAME SIZE WEIGHT SPACING
63 | /// body1 16.0 regular 0.5 (bodyText1)
64 | static final TextStyle body1 = regularStyle.copyWith(
65 | fontSize: Dimens.fontSize16,
66 | letterSpacing: 0.5,
67 | );
68 |
69 | /// NAME SIZE WEIGHT SPACING
70 | /// body2 14.0 regular 0.25 (bodyText2)
71 | static final TextStyle body2 = regularStyle.copyWith(
72 | fontSize: Dimens.fontSize14,
73 | letterSpacing: 0.25,
74 | );
75 |
76 | /// NAME SIZE WEIGHT SPACING
77 | /// button 14.0 medium 1.25
78 | static final TextStyle button = mediumStyle.copyWith(
79 | fontSize: Dimens.fontSize14,
80 | letterSpacing: 1.25,
81 | );
82 |
83 | /// NAME SIZE WEIGHT SPACING
84 | /// caption 12.0 regular 0.4
85 | static final TextStyle caption = regularStyle.copyWith(
86 | fontSize: Dimens.fontSize12,
87 | letterSpacing: .4,
88 | );
89 |
90 | /// NAME SIZE WEIGHT SPACING
91 | /// overline 10.0 regular 1.5
92 | static final TextStyle overline = regularStyle.copyWith(
93 | fontSize: Dimens.fontSize10,
94 | letterSpacing: 1.5,
95 | );
96 |
97 | static final TextStyle lightStyle = _textStyle.copyWith(
98 | fontWeight: FontWeight.w300,
99 | );
100 |
101 | static final TextStyle regularStyle = _textStyle.copyWith(
102 | fontWeight: FontWeight.w400,
103 | );
104 |
105 | static final TextStyle mediumStyle = _textStyle.copyWith(
106 | fontWeight: FontWeight.w500,
107 | );
108 |
109 | static final TextStyle semiBoldStyle = _textStyle.copyWith(
110 | fontWeight: FontWeight.w600,
111 | );
112 |
113 | static final TextStyle boldStyle = _textStyle.copyWith(
114 | fontWeight: FontWeight.w700,
115 | );
116 |
117 | static final TextStyle buttonTextStyle = _textStyle.copyWith(
118 | fontSize: Dimens.fontSize16,
119 | fontWeight: FontWeight.w700,
120 | );
121 |
122 | static const TextStyle _textStyle = TextStyle(
123 | color: Colors.black,
124 | );
125 |
126 | static TextTheme get textTheme => TextTheme(
127 | headline1: headline1,
128 | headline2: headline2,
129 | headline3: headline3,
130 | headline4: headline4,
131 | headline5: headline5,
132 | headline6: headline6,
133 | subtitle1: subtitle1,
134 | subtitle2: subtitle2,
135 | bodyText1: body1,
136 | bodyText2: body2,
137 | caption: caption,
138 | button: button,
139 | overline: overline,
140 | );
141 | }
142 |
--------------------------------------------------------------------------------
/lib/app/common/values/styles/dimens.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_screenutil/flutter_screenutil.dart';
2 |
3 | abstract class Dimens {
4 | static final double fontSize10 = 10.sp;
5 | static final double fontSize12 = 12.sp;
6 | static final double fontSize13 = 13.sp;
7 | static final double fontSize14 = 14.sp;
8 | static final double fontSize15 = 15.sp;
9 | static final double fontSize16 = 16.sp;
10 | static final double fontSize18 = 18.sp;
11 | static final double fontSize20 = 20.sp;
12 | static final double fontSize22 = 22.sp;
13 | static final double fontSize24 = 24.sp;
14 | static final double fontSize26 = 26.sp;
15 | static final double fontSize28 = 28.sp;
16 | static final double fontSize30 = 30.sp;
17 | static final double fontSize32 = 32.sp;
18 | static final double fontSize34 = 34.sp;
19 | static final double fontSize48 = 48.sp;
20 | static final double fontSize60 = 60.sp;
21 | static final double fontSize96 = 96.sp;
22 | }
23 |
--------------------------------------------------------------------------------
/lib/app/common/values/styles/theme.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/extensions.dart';
3 | import 'package:flutter_getx_template/app/common/values/app_colors.dart';
4 | import 'package:flutter_getx_template/app/common/values/styles/app_text_style.dart';
5 | import 'package:flutter_getx_template/app/common/values/styles/dimens.dart';
6 | import 'package:flutter_screenutil/flutter_screenutil.dart';
7 |
8 | abstract class AppTheme {
9 | static ThemeData get theme {
10 | final inputBorder = 16.outlineInputBorder(
11 | borderSide: 3.borderSide(),
12 | );
13 |
14 | final hintStyle = AppTextStyle.semiBoldStyle.copyWith(
15 | color: AppColors.doveGray,
16 | fontSize: Dimens.fontSize14,
17 | );
18 |
19 | return ThemeData(
20 | brightness: Brightness.light,
21 | primaryColor: AppColors.kPrimaryColor,
22 | visualDensity: VisualDensity.adaptivePlatformDensity,
23 | appBarTheme: const AppBarTheme(
24 | color: AppColors.kPrimaryColor,
25 | ),
26 | primaryTextTheme: AppTextStyle.textTheme,
27 | buttonTheme: ButtonThemeData(
28 | buttonColor: AppColors.kPrimaryColor,
29 | height: 45.h,
30 | textTheme: ButtonTextTheme.primary,
31 | shape: RoundedRectangleBorder(
32 | borderRadius: 23.borderRadius,
33 | ),
34 | ),
35 | textButtonTheme: TextButtonThemeData(
36 | style: ButtonStyle(
37 | padding: MaterialStateProperty.resolveWith(
38 | (_) => EdgeInsets.zero,
39 | ),
40 | overlayColor: MaterialStateProperty.resolveWith(
41 | (Set states) {
42 | if (states.contains(MaterialState.pressed)) {
43 | return Colors.white.withOpacity(.14);
44 | }
45 |
46 | return null;
47 | },
48 | ),
49 | textStyle: MaterialStateProperty.resolveWith(
50 | (_) => AppTextStyle.buttonTextStyle,
51 | ),
52 | shape: MaterialStateProperty.resolveWith(
53 | (states) => RoundedRectangleBorder(
54 | borderRadius: 10.borderRadius,
55 | ),
56 | ),
57 | backgroundColor: MaterialStateProperty.resolveWith(
58 | (Set states) {
59 | if (states.contains(MaterialState.disabled)) {
60 | return AppColors.doveGray;
61 | }
62 | return null;
63 | },
64 | ),
65 | ),
66 | ),
67 | elevatedButtonTheme: ElevatedButtonThemeData(
68 | style: ButtonStyle(
69 | padding: MaterialStateProperty.resolveWith(
70 | (_) => EdgeInsets.zero,
71 | ),
72 | overlayColor: MaterialStateProperty.resolveWith(
73 | (Set states) {
74 | if (states.contains(MaterialState.pressed)) {
75 | return Colors.white.withOpacity(.14);
76 | }
77 |
78 | return null;
79 | },
80 | ),
81 | textStyle: MaterialStateProperty.resolveWith(
82 | (_) => AppTextStyle.buttonTextStyle,
83 | ),
84 | shape: MaterialStateProperty.resolveWith(
85 | (states) => RoundedRectangleBorder(
86 | borderRadius: 10.borderRadius,
87 | ),
88 | ),
89 | ),
90 | ),
91 | floatingActionButtonTheme: const FloatingActionButtonThemeData(
92 | elevation: 4,
93 | backgroundColor: AppColors.kPrimaryColor,
94 | ),
95 | textTheme: TextTheme(
96 | subtitle1: AppTextStyle.regularStyle.copyWith(
97 | color: AppColors.mineShaft,
98 | fontSize: Dimens.fontSize14,
99 | ),
100 | ),
101 | inputDecorationTheme: InputDecorationTheme(
102 | filled: true,
103 | contentPadding: const EdgeInsets.symmetric(
104 | horizontal: 12,
105 | vertical: 3,
106 | ),
107 | prefixStyle: AppTextStyle.regularStyle.copyWith(
108 | fontSize: Dimens.fontSize14,
109 | color: AppColors.black,
110 | ),
111 | hintStyle: hintStyle,
112 | labelStyle: hintStyle,
113 | enabledBorder: inputBorder,
114 | disabledBorder: inputBorder,
115 | focusedBorder: inputBorder,
116 | border: inputBorder,
117 | ),
118 | cardTheme: CardTheme(
119 | color: Colors.white.withOpacity(0.85),
120 | shape: RoundedRectangleBorder(
121 | borderRadius: 10.borderRadius,
122 | ),
123 | ),
124 | dialogTheme: DialogTheme(
125 | backgroundColor: Colors.white,
126 | shape: RoundedRectangleBorder(
127 | borderRadius: 20.borderRadius,
128 | ),
129 | ),
130 | bottomSheetTheme: BottomSheetThemeData(
131 | backgroundColor: Colors.white,
132 | shape: RoundedRectangleBorder(
133 | borderRadius: BorderRadius.only(
134 | topLeft: Radius.circular(23.r),
135 | topRight: Radius.circular(23.r),
136 | ),
137 | ),
138 | ),
139 | colorScheme: ColorScheme.fromSwatch().copyWith(
140 | secondary: AppColors.kPrimaryColor,
141 | ),
142 | );
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/lib/app/data/api_helper.dart:
--------------------------------------------------------------------------------
1 | import 'package:get/get.dart';
2 |
3 | export 'package:flutter_getx_template/app/common/util/extensions.dart';
4 | export 'package:flutter_getx_template/app/common/util/utils.dart';
5 |
6 | abstract class ApiHelper {
7 | static ApiHelper get to => Get.find();
8 |
9 | Future getPosts();
10 | }
11 |
--------------------------------------------------------------------------------
/lib/app/data/api_helper_impl.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter_getx_template/app/common/constants.dart';
4 | import 'package:flutter_getx_template/app/common/storage/storage.dart';
5 | import 'package:get/get.dart';
6 |
7 | import 'api_helper.dart';
8 |
9 | class ApiHelperImpl extends GetConnect with ApiHelper {
10 | @override
11 | void onInit() {
12 | httpClient.baseUrl = Constants.baseUrl;
13 | httpClient.timeout = Constants.timeout;
14 |
15 | addRequestModifier();
16 |
17 | httpClient.addResponseModifier((request, response) {
18 | printInfo(
19 | info: 'Status Code: ${response.statusCode}\n'
20 | 'Data: ${response.bodyString?.toString() ?? ''}',
21 | );
22 |
23 | return response;
24 | });
25 | }
26 |
27 | void addRequestModifier() {
28 | httpClient.addRequestModifier((request) {
29 | if (Storage.hasData(Constants.token)) {
30 | request.headers['Authorization'] = Storage.getValue(Constants.token);
31 | }
32 |
33 | printInfo(
34 | info: 'REQUEST ║ ${request.method.toUpperCase()}\n'
35 | 'url: ${request.url}\n'
36 | 'Headers: ${request.headers}\n'
37 | 'Body: ${request.files?.toString() ?? ''}\n',
38 | );
39 |
40 | return request;
41 | });
42 | }
43 |
44 | @override
45 | Future> getPosts() {
46 | return get('posts');
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/app/data/api_response.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:convert';
3 |
4 | import 'package:flutter_getx_template/app/common/values/strings.dart';
5 | import 'package:get/get.dart';
6 | import 'package:get/get_connect/http/src/status/http_status.dart';
7 |
8 | import 'errors/api_error.dart';
9 |
10 | abstract class ApiResponse {
11 | static T? getResponse(Response response) {
12 | final status = response.status;
13 |
14 | if (status.connectionError) {
15 | throw const ApiError(
16 | type: ErrorType.noConnection,
17 | error: Strings.noConnection,
18 | );
19 | }
20 |
21 | if (response.bodyString == null) throw const ApiError();
22 |
23 | try {
24 | String result = response.bodyString!;
25 | final res = jsonDecode(result);
26 |
27 | if (response.isOk) {
28 | if (res is Map) {
29 | if (res['errorcode'] != null &&
30 | res['errorcode'].toString().isNotEmpty) {
31 | if (res['errorcode'].toString() == 'invalidtoken') {
32 | throw const ApiError(
33 | type: ErrorType.response,
34 | error: Strings.unauthorize,
35 | );
36 | } else {
37 | throw ApiError(
38 | type: ErrorType.response,
39 | error: res['msg']?.toString() ??
40 | (res['message']?.toString() ?? Strings.unknownError),
41 | );
42 | }
43 | }
44 | }
45 |
46 | return response.body;
47 | } else {
48 | if (status.isServerError) {
49 | throw const ApiError();
50 | } else if (status.code == HttpStatus.requestTimeout) {
51 | throw const ApiError(
52 | type: ErrorType.connectTimeout,
53 | error: Strings.connectionTimeout,
54 | );
55 | } else if (response.unauthorized) {
56 | throw ApiError(
57 | type: ErrorType.unauthorize,
58 | error: res['msg']?.toString() ?? Strings.unauthorize,
59 | );
60 | } else {
61 | throw ApiError(
62 | type: ErrorType.response,
63 | error: res['msg']?.toString() ?? Strings.unknownError,
64 | );
65 | }
66 | }
67 | } on FormatException {
68 | throw const ApiError(
69 | type: ErrorType.unknownError,
70 | error: Strings.unknownError,
71 | );
72 | } on TimeoutException catch (e) {
73 | throw ApiError(
74 | type: ErrorType.connectTimeout,
75 | error: e.message?.toString() ?? Strings.connectionTimeout,
76 | );
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/lib/app/data/errors/api_error.dart:
--------------------------------------------------------------------------------
1 | enum ErrorType {
2 | /// It occurs when url is opened timeout.
3 | connectTimeout,
4 |
5 | /// It occurs when url is noConnection.
6 | noConnection,
7 |
8 | /// When the server response, but with a incorrect status, such as 404, 503...
9 | response,
10 |
11 | /// When the request is cancelled, dio will throw a error with this type.
12 | cancel,
13 |
14 | /// When the request is unauthorize.
15 | unauthorize,
16 |
17 | /// Default error type, Some other Error. In this case, you can
18 | /// use the ApiError.error if it is not null.
19 | unknownError,
20 | }
21 |
22 | /// ApiError describes the error info when request failed.
23 | class ApiError implements Exception {
24 | const ApiError({
25 | this.type = ErrorType.unknownError,
26 | this.error,
27 | });
28 |
29 | final ErrorType type;
30 |
31 | /// The original error/exception object; It's usually not null when `type`
32 | /// is ErrorType.DEFAULT
33 | final dynamic error;
34 |
35 | String get message => (error?.toString() ?? '');
36 |
37 | @override
38 | String toString() {
39 | var msg = '$type\nmessage: $message';
40 | return msg;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/app/data/interface_controller/api_interface_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter_getx_template/app/data/errors/api_error.dart';
3 | import 'package:get/get.dart';
4 |
5 | class ApiInterfaceController extends GetxController {
6 | ApiError? error;
7 |
8 | VoidCallback? retry;
9 |
10 | void onRetryTap() {
11 | error = null;
12 | retry?.call();
13 | update();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/app/modules/home/bindings/home_binding.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_getx_template/app/modules/home/controllers/home_controller.dart';
2 | import 'package:get/get.dart';
3 |
4 | class HomeBinding extends Bindings {
5 | @override
6 | void dependencies() {
7 | Get.lazyPut(
8 | () => HomeController(),
9 | );
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/lib/app/modules/home/controllers/home_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_getx_template/app/common/storage/storage.dart';
2 | import 'package:flutter_getx_template/app/data/api_helper.dart';
3 | import 'package:get/get.dart';
4 |
5 | class HomeController extends GetxController {
6 | final ApiHelper _apiHelper = ApiHelper.to;
7 |
8 | final RxList _dataList = RxList();
9 | List get dataList => _dataList;
10 | set dataList(List dataList) => _dataList.addAll(dataList);
11 |
12 | @override
13 | void onReady() {
14 | super.onReady();
15 |
16 | getPosts();
17 | }
18 |
19 | void getPosts() {
20 | _apiHelper.getPosts().futureValue(
21 | (value) => dataList = value,
22 | retryFunction: getPosts,
23 | );
24 | }
25 |
26 | void onEditProfileClick() {
27 | Get.back();
28 | }
29 |
30 | void onFaqsClick() {
31 | Get.back();
32 | }
33 |
34 | void onLogoutClick() {
35 | Storage.clearStorage();
36 | // Get.offAllNamed(Routes.HOME);
37 | //Specify the INITIAL SCREEN you want to display to the user after logout
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/app/modules/home/views/home_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/modules/home/controllers/home_controller.dart';
4 | import 'package:flutter_getx_template/app/modules/widgets/base_widget.dart';
5 | import 'package:flutter_getx_template/app/modules/widgets/custom_appbar_widget.dart';
6 | import 'package:get/get.dart';
7 |
8 | class HomeView extends GetView {
9 | const HomeView({Key? key}) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: CustomAppbarWidget(
15 | addBackButton: false,
16 | title: Strings.home,
17 | ),
18 | body: Obx(
19 | () {
20 | return ListView.separated(
21 | separatorBuilder: (context, index) => SizedBox(height: 10.h),
22 | itemCount: controller.dataList.length,
23 | padding: const EdgeInsets.all(16),
24 | shrinkWrap: true,
25 | itemBuilder: (context, index) {
26 | final dynamic _data = controller.dataList[index];
27 |
28 | return Column(
29 | mainAxisSize: MainAxisSize.min,
30 | crossAxisAlignment: CrossAxisAlignment.start,
31 | children: [
32 | Text(
33 | 'Title: ${_data['title'].toString()}',
34 | ),
35 | SizedBox(height: 5.h),
36 | Text(
37 | 'Body: ${_data['body'].toString()}',
38 | ),
39 | ],
40 | );
41 | },
42 | );
43 | },
44 | ),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/base_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/data/interface_controller/api_interface_controller.dart';
3 | import 'package:flutter_getx_template/app/modules/widgets/custom_retry_widget.dart';
4 | import 'package:get/get.dart';
5 |
6 | export 'package:flutter_getx_template/app/common/util/exports.dart';
7 |
8 | class BaseWidget extends StatelessWidget {
9 | ///A widget with only custom retry button widget.
10 | final Widget child;
11 |
12 | const BaseWidget({
13 | Key? key,
14 | required this.child,
15 | }) : super(key: key);
16 | @override
17 | Widget build(BuildContext context) {
18 | return GetBuilder(
19 | builder: (c) => Stack(
20 | children: [
21 | Positioned.fill(
22 | child: child,
23 | ),
24 | Visibility(
25 | visible: c.retry != null && c.error != null,
26 | child: Positioned.fill(
27 | child: Scaffold(
28 | body: CustomRetryWidget(
29 | onPressed: c.onRetryTap,
30 | ),
31 | ),
32 | ),
33 | ),
34 | ],
35 | ),
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_appbar_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/modules/widgets/custom_back_button.dart';
4 |
5 | class CustomAppbarWidget extends PreferredSize {
6 | final String? title;
7 | final Color? backgroundColor, backbuttonColor, textColor;
8 | final TextStyle? textStyle;
9 | final List? actions;
10 | final Function()? onActionButtonTap, onBackPress;
11 | final double? actionButtonWidth;
12 | final Widget? titleWidget, leading, bottom;
13 | final bool addBackButton;
14 | final bool? centerTitle;
15 |
16 | CustomAppbarWidget({
17 | Key? key,
18 | this.title,
19 | this.titleWidget,
20 | this.leading,
21 | this.addBackButton = true,
22 | this.onBackPress,
23 | this.backgroundColor = AppColors.kPrimaryColor,
24 | this.backbuttonColor = Colors.white,
25 | this.textColor,
26 | this.textStyle,
27 | this.actions,
28 | this.onActionButtonTap,
29 | this.actionButtonWidth = 100,
30 | this.bottom,
31 | this.centerTitle,
32 | }) : assert(
33 | textColor == null || textStyle == null,
34 | 'Cannot provide both a textColor and a textStyle\n'
35 | 'To provide both, use "textStyle: TextStyle(color: color)".',
36 | ),
37 | super(
38 | key: key,
39 | child: const SizedBox.shrink(),
40 | preferredSize:
41 | Size.fromHeight(bottom == null ? kToolbarHeight : 98.h),
42 | );
43 |
44 | @override
45 | Widget build(BuildContext context) {
46 | return AppBar(
47 | centerTitle: centerTitle,
48 | elevation: 0,
49 | actions: actions,
50 | actionsIconTheme: IconThemeData(
51 | size: 20.w,
52 | ),
53 | bottom: bottom == null
54 | ? null
55 | : PreferredSize(
56 | preferredSize: Size.fromHeight(100.h),
57 | child: bottom!,
58 | ),
59 | leading: addBackButton
60 | ? CustomBackButton(
61 | leading: leading,
62 | onBackTap: onBackPress,
63 | backbuttonColor: backbuttonColor,
64 | )
65 | : null,
66 | leadingWidth: 45.w,
67 | backgroundColor: backgroundColor,
68 | title: title == null
69 | ? (titleWidget ?? const SizedBox.shrink())
70 | : Text(
71 | title!,
72 | style: textStyle ??
73 | AppTextStyle.boldStyle.copyWith(
74 | color: textColor ??
75 | (backgroundColor == Colors.white
76 | ? AppColors.mineShaft
77 | : Colors.white),
78 | fontSize: Dimens.fontSize18,
79 | ),
80 | ),
81 | );
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_back_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:get/get.dart';
4 |
5 | class CustomBackButton extends StatelessWidget {
6 | final Widget? leading;
7 | final Function()? onBackTap;
8 | final Color? backbuttonColor;
9 |
10 | const CustomBackButton({
11 | Key? key,
12 | this.leading,
13 | this.onBackTap,
14 | this.backbuttonColor,
15 | }) : super(key: key);
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return IconButton(
20 | onPressed: onBackTap ?? () => Get.back(),
21 | icon: leading ??
22 | Icon(
23 | Icons.arrow_back,
24 | color: backbuttonColor ?? Get.theme.primaryIconTheme.color,
25 | ).paddingOnly(left: 10.w),
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_card_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/modules/widgets/stroke_background.dart';
4 |
5 | class CustomCardWidget extends StatelessWidget {
6 | final Widget? trailing;
7 | final String? title, trailingText, leadingImage;
8 | final Function() onTap;
9 | final bool addForwardIcon;
10 |
11 | const CustomCardWidget({
12 | Key? key,
13 | this.leadingImage,
14 | required this.title,
15 | this.trailing,
16 | required this.onTap,
17 | this.trailingText,
18 | this.addForwardIcon = true,
19 | }) : assert(trailingText == null || trailing == null, Strings.error),
20 | super(key: key);
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return StrokeBackground(
25 | onTap: onTap,
26 | height: 68,
27 | child: Row(
28 | children: [
29 | if (leadingImage != null) ...[
30 | leadingImage!.imageAsset(
31 | size: Size(24.w, 24.w),
32 | ),
33 | SizedBox(width: 10.w),
34 | ],
35 | Text(
36 | title!,
37 | style: AppTextStyle.regularStyle.copyWith(
38 | color: AppColors.black,
39 | fontSize: Dimens.fontSize16,
40 | ),
41 | ),
42 | if (trailing != null) ...[
43 | const Spacer(),
44 | trailing!
45 | ] else if (trailingText != null) ...[
46 | const Spacer(),
47 | CircleAvatar(
48 | radius: 12.r,
49 | backgroundColor: AppColors.amaranth,
50 | child: Text(
51 | trailingText!,
52 | style: AppTextStyle.regularStyle.copyWith(
53 | color: Colors.white,
54 | ),
55 | ),
56 | ),
57 | ] else
58 | const SizedBox.shrink(),
59 | if (addForwardIcon) ...[
60 | if (trailing == null && trailingText == null)
61 | const Spacer()
62 | else
63 | SizedBox(width: 10.w),
64 | const Icon(Icons.arrow_forward_ios_sharp),
65 | ],
66 | ],
67 | ),
68 | );
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_checkbox_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/validators.dart';
3 |
4 | class CustomCheckboxWidget extends FormField {
5 | CustomCheckboxWidget({
6 | Key? key,
7 | required bool value,
8 | required FormFieldSetter onSaved,
9 | required Widget titleWidget,
10 | }) : super(
11 | key: key,
12 | initialValue: value,
13 | onSaved: onSaved,
14 | autovalidateMode: AutovalidateMode.onUserInteraction,
15 | validator: (v) => Validators.validateCheckbox(v: v!),
16 | builder: (state) {
17 | return CheckboxListTile(
18 | dense: state.hasError,
19 | value: state.value,
20 | contentPadding: EdgeInsets.zero,
21 | controlAffinity: ListTileControlAffinity.leading,
22 | onChanged: state.didChange,
23 | title: titleWidget,
24 | subtitle: state.hasError
25 | ? Builder(
26 | builder: (_) => Text(
27 | state.errorText!,
28 | style: TextStyle(color: Theme.of(_).errorColor),
29 | ),
30 | )
31 | : null,
32 | );
33 | },
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_drawer_header.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/modules/home/controllers/home_controller.dart';
4 | import 'package:flutter_getx_template/app/modules/widgets/custom_row_text_widget.dart';
5 |
6 | class CustomDrawerHeader extends StatelessWidget {
7 | final HomeController homeController;
8 |
9 | const CustomDrawerHeader({
10 | Key? key,
11 | required this.homeController,
12 | }) : super(key: key);
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return Container(
17 | padding: EdgeInsets.fromLTRB(15.w, 15.w, 15.w, 7.w),
18 | child: Row(
19 | children: [
20 | ClipRRect(
21 | borderRadius: 5.borderRadius,
22 | child: FadeInImage.assetNetwork(
23 | placeholder: AppImages.icGallery,
24 | width: 60.w,
25 | height: 60.w,
26 | fit: BoxFit.cover,
27 | image: 'https://dummyimage.com/600x400/000/fff.jpg',
28 | imageErrorBuilder: (_, e, s) => const Icon(Icons.offline_bolt),
29 | ),
30 | ),
31 | Expanded(
32 | child: Padding(
33 | padding: EdgeInsets.all(15.w),
34 | child: Column(
35 | mainAxisSize: MainAxisSize.min,
36 | crossAxisAlignment: CrossAxisAlignment.start,
37 | children: [
38 | Row(
39 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
40 | children: [
41 | Text(
42 | 'First name',
43 | style: AppTextStyle.semiBoldStyle.copyWith(
44 | fontSize: Dimens.fontSize16,
45 | ),
46 | ),
47 | InkWell(
48 | onTap: homeController.onEditProfileClick,
49 | child: const Icon(Icons.edit),
50 | )
51 | ],
52 | ),
53 | SizedBox(height: 4.w),
54 | const CustomRowTextWidget(
55 | title: '${Strings.mobile}: ',
56 | subtitle: '+91123456789',
57 | ),
58 | ],
59 | ),
60 | ),
61 | ),
62 | ],
63 | ),
64 | );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_drawer_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/modules/home/controllers/home_controller.dart';
4 | import 'package:flutter_getx_template/app/modules/widgets/custom_drawer_header.dart';
5 | import 'package:flutter_getx_template/app/modules/widgets/custom_listtile_widget.dart';
6 |
7 | class CustomDrawerWidget extends StatelessWidget {
8 | final HomeController controller;
9 |
10 | const CustomDrawerWidget({
11 | Key? key,
12 | required this.controller,
13 | }) : super(key: key);
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | return SafeArea(
18 | child: Drawer(
19 | child: Column(
20 | crossAxisAlignment: CrossAxisAlignment.start,
21 | children: [
22 | CustomDrawerHeader(
23 | homeController: controller,
24 | ),
25 | Padding(
26 | padding: EdgeInsets.symmetric(horizontal: 15.w),
27 | child: Divider(
28 | thickness: 2.w,
29 | color: AppColors.doveGray.withOpacity(0.5),
30 | ),
31 | ),
32 | Expanded(
33 | child: ListView(
34 | padding: EdgeInsets.zero,
35 | children: [
36 | CustomListTileWidget(
37 | title: Strings.gallery,
38 | onTap: controller.onFaqsClick,
39 | ),
40 | ],
41 | ),
42 | ),
43 | CustomListTileWidget(
44 | title: Strings.logOut,
45 | onTap: controller.onLogoutClick,
46 | ),
47 | ],
48 | ),
49 | ),
50 | );
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_dropdown_textfield.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/common/util/validators.dart';
4 |
5 | class CustomDropdownTextField extends StatelessWidget {
6 | final String title;
7 | final ValueChanged onChanged;
8 | final FormFieldSetter? onSaved;
9 | final List dataList;
10 | final String Function(T data)? item;
11 | final double? width;
12 | final T? value;
13 | final double? textFontSize;
14 |
15 | const CustomDropdownTextField({
16 | Key? key,
17 | required this.title,
18 | required this.dataList,
19 | required this.item,
20 | required this.onChanged,
21 | this.onSaved,
22 | this.width,
23 | this.value,
24 | this.textFontSize,
25 | }) : super(key: key);
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return dataList.isNotEmpty
30 | ? SizedBox(
31 | width: width?.w,
32 | child: DropdownButtonFormField(
33 | isExpanded: true,
34 | icon: const Icon(Icons.arrow_drop_down),
35 | value: value,
36 | decoration: InputDecoration(
37 | filled: true,
38 | hintText: value == null ? '' : item!(value!),
39 | labelText: title,
40 | hintStyle: AppTextStyle.regularStyle.copyWith(
41 | fontSize: textFontSize ?? Dimens.fontSize14,
42 | color: AppColors.mineShaft,
43 | ),
44 | floatingLabelBehavior: value == null || item == null
45 | ? FloatingLabelBehavior.never
46 | : FloatingLabelBehavior.always,
47 | fillColor: Colors.white,
48 | contentPadding: EdgeInsets.symmetric(horizontal: 12.w),
49 | ),
50 | autovalidateMode: AutovalidateMode.onUserInteraction,
51 | validator: Validators.validateTEmpty,
52 | onChanged: onChanged,
53 | onSaved: onSaved,
54 | items: dataList
55 | .map>(
56 | (e) => DropdownMenuItem(
57 | value: e,
58 | child: Text(
59 | item!(e),
60 | maxLines: 1,
61 | overflow: TextOverflow.ellipsis,
62 | style: AppTextStyle.regularStyle.copyWith(
63 | fontSize: textFontSize ?? Dimens.fontSize14,
64 | color: AppColors.mineShaft,
65 | ),
66 | ),
67 | ),
68 | )
69 | .toList(),
70 | ),
71 | )
72 | : const SizedBox.shrink();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_elevated_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomElevatedButton extends StatelessWidget {
5 | final String? title;
6 | final VoidCallback onPressed;
7 | final TextStyle? textStyle;
8 | final double height, minWidth;
9 | final Widget? titleWidget;
10 | final Color buttonColor;
11 | final bool addBorder;
12 |
13 | const CustomElevatedButton({
14 | Key? key,
15 | this.title,
16 | required this.onPressed,
17 | this.textStyle,
18 | this.height = 52,
19 | this.minWidth = 100,
20 | this.buttonColor = AppColors.kPrimaryColor,
21 | this.titleWidget,
22 | this.addBorder = false,
23 | }) : assert(
24 | title == null || titleWidget == null,
25 | 'Cannot provide both a title and a child\n'
26 | 'To provide both, use "titleWidget: Text(title)".',
27 | ),
28 | super(key: key);
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return ElevatedButton(
33 | onPressed: onPressed,
34 | style: ButtonStyle(
35 | minimumSize: MaterialStateProperty.resolveWith(
36 | (states) => Size(
37 | minWidth.w,
38 | height.h,
39 | ),
40 | ),
41 | shape: addBorder
42 | ? MaterialStateProperty.resolveWith(
43 | (states) => RoundedRectangleBorder(
44 | borderRadius: 10.borderRadius,
45 | side: BorderSide(
46 | color: buttonColor == AppColors.kPrimaryColor
47 | ? Colors.white
48 | : AppColors.kPrimaryColor,
49 | width: 2.w,
50 | ),
51 | ),
52 | )
53 | : AppTheme.theme.textButtonTheme.style!.shape,
54 | overlayColor: MaterialStateProperty.resolveWith(
55 | (Set states) {
56 | if (states.contains(MaterialState.pressed)) {
57 | return buttonColor == Colors.transparent ||
58 | buttonColor == Colors.white
59 | ? AppColors.kPrimaryColor.withOpacity(.24)
60 | : Colors.white.withOpacity(.14);
61 | }
62 |
63 | return null;
64 | },
65 | ),
66 | backgroundColor: MaterialStateProperty.resolveWith(
67 | (Set states) {
68 | if (states.contains(MaterialState.disabled)) {
69 | return AppColors.doveGray;
70 | }
71 | return buttonColor;
72 | },
73 | ),
74 | ),
75 | child: titleWidget ??
76 | Text(
77 | title!,
78 | style: textStyle ??
79 | AppTextStyle.boldStyle.copyWith(
80 | fontSize: Dimens.fontSize14,
81 | color: buttonColor == Colors.white ||
82 | buttonColor == Colors.transparent
83 | ? AppColors.kPrimaryColor
84 | : Colors.white,
85 | ),
86 | ),
87 | );
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_error_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:get/get.dart';
4 |
5 | class CustomErrorWidget extends StatelessWidget {
6 | final String? message;
7 |
8 | const CustomErrorWidget({
9 | Key? key,
10 | this.message,
11 | }) : super(key: key);
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Scaffold(
16 | body: Center(
17 | child: Text(
18 | message ?? Strings.somethingWentWrong,
19 | style: Get.textTheme.headline5,
20 | ),
21 | ),
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_image_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_getx_template/app/common/constants.dart';
5 | import 'package:flutter_getx_template/app/common/util/exports.dart';
6 | import 'package:get/get.dart';
7 | import 'package:octo_image/octo_image.dart';
8 |
9 | class CustomImageWidget extends StatelessWidget {
10 | final String? imageUrl;
11 | final Size? size;
12 | final double? height, radius;
13 | final BorderRadius? borderRadius;
14 | final Color? color;
15 |
16 | const CustomImageWidget({
17 | Key? key,
18 | required this.imageUrl,
19 | this.size,
20 | this.radius,
21 | this.borderRadius,
22 | this.color,
23 | this.height,
24 | }) : assert(
25 | borderRadius == null || radius == null,
26 | 'Cannot provide both a borderRadius and a radius\n',
27 | ),
28 | super(key: key);
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return (radius != null || borderRadius != null)
33 | ? ClipRRect(
34 | borderRadius: borderRadius ?? radius?.borderRadius,
35 | child: child,
36 | )
37 | : child;
38 | }
39 |
40 | Widget get child =>
41 | imageUrl == null || (imageUrl != null && imageUrl!.isEmpty)
42 | ? placeholder
43 | : (GetUtils.isURL(imageUrl ?? Constants.dummyImageUrl) ||
44 | imageUrl!.startsWith('https') ||
45 | imageUrl!.startsWith('http')
46 | ? OctoImage(
47 | image: NetworkImage(
48 | imageUrl ?? Constants.dummyImageUrl,
49 | ),
50 | placeholderBuilder: OctoPlaceholder.blurHash(
51 | Constants.placeHolderBlurHash,
52 | ),
53 | errorBuilder: (context, error, stackTrace) {
54 | return placeholder;
55 | },
56 | fit: BoxFit.cover,
57 | width: size?.width.w,
58 | height: height?.w ?? size?.height.w,
59 | color: color,
60 | )
61 | : (File(imageUrl!).existsSync()
62 | ? Image.file(
63 | File(imageUrl!),
64 | width: size?.width.w,
65 | height: height?.w ?? size?.height.w,
66 | fit: BoxFit.cover,
67 | )
68 | : placeholder));
69 |
70 | Widget get placeholder => Icon(
71 | Icons.error,
72 | size: size?.width.w,
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_inkwell_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:get/get.dart';
4 |
5 | class CustomInkwellWidget extends Material {
6 | CustomInkwellWidget({
7 | Key? key,
8 | required Function() onTap,
9 | required Widget child,
10 | }) : super(
11 | key: key,
12 | color: Colors.transparent,
13 | child: InkWell(
14 | onTap: onTap,
15 | splashColor: AppColors.kPrimaryColor.withOpacity(0.24),
16 | child: child.paddingAll(8),
17 | ),
18 | );
19 |
20 | CustomInkwellWidget.text({
21 | Key? key,
22 | required Function() onTap,
23 | required String title,
24 | TextStyle? textStyle,
25 | Color? textColor,
26 | double? textSize,
27 | }) : assert(
28 | textColor == null || textStyle == null,
29 | 'Cannot provide both a textColor and a textStyle\n'
30 | 'To provide both, use "textStyle: TextStyle(color: color)".',
31 | ),
32 | assert(
33 | textSize == null || textStyle == null,
34 | 'Cannot provide both a textSize and a textStyle\n'
35 | 'To provide both, use "textStyle: TextStyle(size: textSize)".',
36 | ),
37 | super(
38 | key: key,
39 | color: Colors.transparent,
40 | child: InkWell(
41 | onTap: onTap,
42 | child: Text(
43 | title,
44 | style: textStyle ??
45 | AppTextStyle.regularStyle.copyWith(
46 | color: textColor,
47 | fontSize: textSize,
48 | ),
49 | ).paddingAll(8),
50 | ),
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_listtile_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomListTileWidget extends StatelessWidget {
5 | final String title;
6 | final Function() onTap;
7 | final Widget? trailing;
8 |
9 | const CustomListTileWidget({
10 | Key? key,
11 | required this.title,
12 | required this.onTap,
13 | this.trailing,
14 | }) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return ListTile(
19 | onTap: onTap,
20 | title: Text(
21 | title,
22 | style: AppTextStyle.semiBoldStyle.copyWith(
23 | color: AppColors.black,
24 | fontSize: Dimens.fontSize16,
25 | ),
26 | ),
27 | trailing: trailing ?? const Icon(Icons.arrow_forward_ios_sharp),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_on_board_card_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomOnBoardCardWidget extends StatelessWidget {
5 | final String title, subtitle;
6 | final double? titleTextSize, subtitleTextSize;
7 | final List children;
8 |
9 | const CustomOnBoardCardWidget({
10 | Key? key,
11 | required this.children,
12 | required this.title,
13 | required this.subtitle,
14 | this.titleTextSize,
15 | this.subtitleTextSize,
16 | }) : super(key: key);
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Center(
21 | child: Container(
22 | margin: const EdgeInsets.all(10),
23 | decoration: BoxDecoration(
24 | color: Colors.white.withOpacity(0.85),
25 | borderRadius: 10.borderRadius,
26 | ),
27 | child: SingleChildScrollView(
28 | padding: const EdgeInsets.all(10),
29 | child: Column(
30 | mainAxisSize: MainAxisSize.min,
31 | crossAxisAlignment: CrossAxisAlignment.stretch,
32 | children: [
33 | Text(
34 | title,
35 | style: AppTextStyle.semiBoldStyle.copyWith(
36 | color: Colors.black,
37 | fontSize: titleTextSize ?? Dimens.fontSize28,
38 | ),
39 | ),
40 | SizedBox(height: 5.h),
41 | Text(
42 | subtitle,
43 | style: AppTextStyle.regularStyle.copyWith(
44 | color: AppColors.mineShaft.withOpacity(0.65),
45 | fontSize: subtitleTextSize ?? Dimens.fontSize16,
46 | ),
47 | ),
48 | SizedBox(height: 22.h),
49 | ...children,
50 | ],
51 | ),
52 | ),
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_password_field.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 | import 'package:flutter_getx_template/app/common/util/validators.dart';
4 |
5 | class PasswordFieldWidget extends StatelessWidget {
6 | final String? title, initialValue;
7 | final TextEditingController? controller;
8 | final bool obscureText;
9 | final Function() onObscureIconClick;
10 | final ValueChanged? onChanged, onSaved;
11 | final Widget? prefixIcon;
12 | final FormFieldValidator validator;
13 | final TextInputAction textInputAction;
14 |
15 | const PasswordFieldWidget({
16 | Key? key,
17 | this.controller,
18 | required this.obscureText,
19 | required this.onObscureIconClick,
20 | this.title,
21 | this.onChanged,
22 | this.onSaved,
23 | this.initialValue,
24 | this.validator = Validators.validatePassword,
25 | this.textInputAction = TextInputAction.next,
26 | this.prefixIcon,
27 | }) : super(key: key);
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return TextFormField(
32 | initialValue: initialValue,
33 | autovalidateMode: AutovalidateMode.onUserInteraction,
34 | obscureText: obscureText,
35 | textInputAction: textInputAction,
36 | validator: validator,
37 | onChanged: onChanged,
38 | onSaved: onSaved,
39 | decoration: InputDecoration(
40 | labelText: title ?? Strings.password,
41 | prefixIcon: prefixIcon,
42 | suffixIcon: IconButton(
43 | onPressed: onObscureIconClick,
44 | color: AppColors.kPrimaryColor,
45 | icon: Icon(
46 | obscureText ? Icons.visibility_off : Icons.visibility,
47 | size: 20.w,
48 | ),
49 | ),
50 | ),
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_retry_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | import 'custom_text_button.dart';
5 |
6 | class CustomRetryWidget extends StatelessWidget {
7 | final String error;
8 | final VoidCallback onPressed;
9 |
10 | const CustomRetryWidget({
11 | Key? key,
12 | required this.onPressed,
13 | this.error = Strings.somethingWentWrong,
14 | }) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return Center(
19 | child: Column(
20 | mainAxisAlignment: MainAxisAlignment.center,
21 | mainAxisSize: MainAxisSize.min,
22 | children: [
23 | Text(error),
24 | SizedBox(height: 16.h),
25 | CustomTextButton(
26 | buttonWidth: 85.w,
27 | height: 45,
28 | onPressed: onPressed,
29 | title: Strings.retry,
30 | ),
31 | ],
32 | ),
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_rich_text_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomRichTextWidget extends StatelessWidget {
5 | final String title, subtitle;
6 | final TextStyle? titleStyle, subtitleStyle;
7 | final TextAlign textAlign;
8 |
9 | const CustomRichTextWidget({
10 | Key? key,
11 | required this.title,
12 | required this.subtitle,
13 | this.titleStyle,
14 | this.subtitleStyle,
15 | this.textAlign = TextAlign.center,
16 | }) : super(key: key);
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return RichText(
21 | textAlign: textAlign,
22 | text: TextSpan(
23 | text: title,
24 | style: titleStyle ??
25 | AppTextStyle.regularStyle.copyWith(
26 | color: AppColors.mineShaft,
27 | fontSize: Dimens.fontSize14,
28 | ),
29 | children: [
30 | TextSpan(
31 | text: ' $subtitle',
32 | style: subtitleStyle ??
33 | AppTextStyle.regularStyle.copyWith(
34 | fontSize: Dimens.fontSize14,
35 | ),
36 | ),
37 | ],
38 | ),
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_row_text_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomRowTextWidget extends StatelessWidget {
5 | final String title, subtitle;
6 | final TextStyle? titleStyle, subtitleStyle;
7 | final MainAxisAlignment mainAxisAlignment;
8 |
9 | const CustomRowTextWidget({
10 | Key? key,
11 | required this.title,
12 | required this.subtitle,
13 | this.titleStyle,
14 | this.subtitleStyle,
15 | this.mainAxisAlignment = MainAxisAlignment.spaceBetween,
16 | }) : super(key: key);
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Row(
21 | crossAxisAlignment: CrossAxisAlignment.start,
22 | mainAxisAlignment: mainAxisAlignment,
23 | children: [
24 | Text(
25 | title,
26 | maxLines: 1,
27 | style: titleStyle ??
28 | AppTextStyle.regularStyle.copyWith(
29 | color: AppColors.mineShaft,
30 | ),
31 | ),
32 | Text(
33 | subtitle,
34 | maxLines: 1,
35 | overflow: TextOverflow.ellipsis,
36 | style: subtitleStyle ??
37 | AppTextStyle.regularStyle.copyWith(
38 | color: Colors.black,
39 | ),
40 | ),
41 | ],
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_text_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class CustomTextButton extends StatelessWidget {
5 | final VoidCallback onPressed;
6 | final String? title;
7 | final double height;
8 | final double? buttonWidth, textFontSize;
9 | final Widget? child;
10 | final Color buttonColor;
11 | final bool addBorder;
12 |
13 | const CustomTextButton({
14 | Key? key,
15 | required this.onPressed,
16 | this.title,
17 | this.height = 52,
18 | this.child,
19 | this.buttonColor = AppColors.kPrimaryColor,
20 | this.buttonWidth,
21 | this.textFontSize,
22 | this.addBorder = false,
23 | }) : assert(
24 | title == null || child == null,
25 | 'Cannot provide both a title and a child\n'
26 | 'To provide both, use "child: Text(title)".',
27 | ),
28 | super(key: key);
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return TextButton(
33 | onPressed: onPressed,
34 | style: AppTheme.theme.textButtonTheme.style!.copyWith(
35 | minimumSize: MaterialStateProperty.resolveWith(
36 | (states) => buttonWidth == null
37 | ? Size.fromHeight(height.h)
38 | : Size(
39 | buttonWidth!,
40 | height.h,
41 | ),
42 | ),
43 | overlayColor: MaterialStateProperty.resolveWith(
44 | (Set states) {
45 | if (states.contains(MaterialState.pressed)) {
46 | return buttonColor == Colors.transparent ||
47 | buttonColor == Colors.white
48 | ? AppColors.kPrimaryColor.withOpacity(.24)
49 | : Colors.white.withOpacity(.14);
50 | }
51 |
52 | return null;
53 | },
54 | ),
55 | shape: addBorder
56 | ? MaterialStateProperty.resolveWith(
57 | (states) => RoundedRectangleBorder(
58 | borderRadius: 23.borderRadius,
59 | side: BorderSide(
60 | color: buttonColor == AppColors.kPrimaryColor
61 | ? Colors.white
62 | : AppColors.kPrimaryColor,
63 | width: 2.w,
64 | ),
65 | ),
66 | )
67 | : AppTheme.theme.textButtonTheme.style!.shape,
68 | backgroundColor: MaterialStateProperty.resolveWith(
69 | (Set states) {
70 | if (states.contains(MaterialState.disabled)) {
71 | return AppColors.doveGray;
72 | }
73 |
74 | return buttonColor;
75 | },
76 | ),
77 | ),
78 | child: child ??
79 | Text(
80 | title!,
81 | style: AppTextStyle.buttonTextStyle.copyWith(
82 | fontSize: textFontSize ?? Dimens.fontSize16,
83 | color: buttonColor == Colors.white ||
84 | buttonColor == Colors.transparent
85 | ? AppColors.kPrimaryColor
86 | : Colors.white,
87 | ),
88 | ),
89 | );
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/custom_text_field_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:flutter_getx_template/app/common/util/exports.dart';
4 | import 'package:flutter_getx_template/app/common/util/validators.dart';
5 |
6 | class CustomTextFieldWidget extends StatelessWidget {
7 | final String? labelText, hintText;
8 | final String? initialValue, prefixText, suffixText;
9 | final Widget? prefixIcon, suffixIcon;
10 | final TextInputType keyboardType;
11 | final FormFieldValidator? validator;
12 | final TextEditingController? controller;
13 | final ValueChanged? onChanged, onSaved;
14 | final int? maxLength, maxLines;
15 | final int minLines;
16 | final bool readOnly, addHint, enabled;
17 | final bool? isDense;
18 | final Function()? onTap;
19 | final InputBorder? border;
20 | final AutovalidateMode autovalidateMode;
21 | final BoxConstraints? suffixIconConstraints;
22 | final EdgeInsets? prefixIconPadding;
23 | final Color? fillColor;
24 |
25 | const CustomTextFieldWidget({
26 | Key? key,
27 | this.labelText,
28 | this.hintText,
29 | this.controller,
30 | this.prefixIcon,
31 | this.suffixIcon,
32 | this.keyboardType = TextInputType.text,
33 | this.validator = Validators.validateEmpty,
34 | this.onChanged,
35 | this.onSaved,
36 | this.maxLength,
37 | this.maxLines,
38 | this.minLines = 1,
39 | this.initialValue,
40 | this.readOnly = false,
41 | this.onTap,
42 | this.border,
43 | this.enabled = true,
44 | this.autovalidateMode = AutovalidateMode.onUserInteraction,
45 | this.addHint = false,
46 | this.suffixIconConstraints,
47 | this.prefixText,
48 | this.suffixText,
49 | this.isDense,
50 | this.prefixIconPadding,
51 | this.fillColor,
52 | }) : super(key: key);
53 |
54 | @override
55 | Widget build(BuildContext context) {
56 | final textStyle = AppTextStyle.regularStyle.copyWith(
57 | color: AppColors.mineShaft,
58 | fontSize: Dimens.fontSize15,
59 | );
60 |
61 | return TextFormField(
62 | onTap: onTap,
63 | readOnly: readOnly,
64 | initialValue: initialValue,
65 | keyboardType: keyboardType,
66 | autovalidateMode: autovalidateMode,
67 | controller: controller,
68 | validator: validator,
69 | onChanged: onChanged,
70 | minLines: minLines,
71 | maxLines: maxLines,
72 | onSaved: onSaved,
73 | enabled: enabled,
74 | inputFormatters: maxLength == null
75 | ? null
76 | : [
77 | LengthLimitingTextInputFormatter(maxLength),
78 | if (keyboardType == TextInputType.number)
79 | FilteringTextInputFormatter.digitsOnly,
80 | ],
81 | decoration: InputDecoration(
82 | fillColor: fillColor,
83 | filled: fillColor != null,
84 | isDense: isDense,
85 | border: border,
86 | enabledBorder: border,
87 | focusedBorder: border,
88 | // alignLabelWithHint: maxLines == null,
89 | labelText: addHint
90 | ? null
91 | : ((controller?.text != null || !readOnly) ? labelText : null),
92 | hintText: hintText,
93 | prefixIconConstraints: BoxConstraints(
94 | maxHeight: 40.h,
95 | maxWidth: 40.w,
96 | ),
97 | prefixIcon: prefixIcon == null
98 | ? null
99 | : Padding(
100 | padding: prefixIconPadding ?? EdgeInsets.only(right: 10.w),
101 | child: prefixIcon,
102 | ),
103 | prefixText: prefixText,
104 | suffixText: suffixText,
105 | prefixStyle: textStyle,
106 | suffixStyle: textStyle,
107 | suffixIcon: suffixIcon == null
108 | ? null
109 | : Padding(
110 | padding: EdgeInsets.symmetric(horizontal: 10.w),
111 | child: suffixIcon,
112 | ),
113 | suffixIconConstraints: suffixIconConstraints ??
114 | BoxConstraints(
115 | maxHeight: 40.h,
116 | maxWidth: 40.w,
117 | ),
118 | ),
119 | );
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/on_boarding_base_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/data/interface_controller/api_interface_controller.dart';
3 | import 'package:flutter_getx_template/app/modules/widgets/custom_retry_widget.dart';
4 | import 'package:get/get.dart';
5 |
6 | export 'package:flutter_getx_template/app/common/util/exports.dart';
7 |
8 | class OnBoardingBaseWidget extends GetView {
9 | ///A widget with custom background and custom retry button widget.
10 | ///You've to add "backgroundColor: Colors.transparent" in Scaffold
11 | ///in order to see backgroundImage properly.
12 |
13 | final Widget child;
14 | final Color? backgroundColor;
15 | final bool addBackgroundImage;
16 | final Alignment alignment;
17 |
18 | const OnBoardingBaseWidget({
19 | Key? key,
20 | required this.child,
21 | this.backgroundColor,
22 | this.addBackgroundImage = false,
23 | this.alignment = Alignment.center,
24 | }) : super(key: key);
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Obx(
29 | () => controller.error != null
30 | ? SafeArea(
31 | child: CustomRetryWidget(
32 | onPressed: () {
33 | controller.error = null;
34 | if (controller.retry != null) {
35 | controller.retry!();
36 | }
37 | },
38 | ),
39 | )
40 | : Container(
41 | height: Get.height,
42 | alignment: alignment,
43 | decoration: BoxDecoration(
44 | color: (!addBackgroundImage && backgroundColor == null)
45 | ? Colors.white
46 | : backgroundColor,
47 | // image: !addBackgroundImage
48 | // ? null
49 | // : DecorationImage(
50 | // fit: BoxFit.cover,
51 | // image: AssetImage(AppImages.backgroundImage),
52 | // ),
53 | //
54 | //add background here
55 | ),
56 | child: SafeArea(
57 | child: child,
58 | ),
59 | ),
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/app/modules/widgets/stroke_background.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/exports.dart';
3 |
4 | class StrokeBackground extends StatelessWidget {
5 | final Widget child;
6 | final Function() onTap;
7 | final double? height;
8 |
9 | const StrokeBackground({
10 | Key? key,
11 | required this.onTap,
12 | required this.child,
13 | this.height,
14 | }) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return InkWell(
19 | borderRadius: 10.borderRadius,
20 | onTap: onTap,
21 | child: Container(
22 | height: height?.h,
23 | padding: EdgeInsets.symmetric(
24 | horizontal: 10.w,
25 | vertical: 10.h,
26 | ),
27 | decoration: BoxDecoration(
28 | borderRadius: 10.borderRadius,
29 | border: Border.all(
30 | color: Colors.grey[200]!,
31 | width: 3.w,
32 | ),
33 | ),
34 | child: child,
35 | ),
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/app/routes/app_pages.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_getx_template/app/modules/home/bindings/home_binding.dart';
2 | import 'package:flutter_getx_template/app/modules/home/views/home_view.dart';
3 | import 'package:get/get.dart';
4 |
5 | part 'app_routes.dart';
6 |
7 | abstract class AppPages {
8 | const AppPages._();
9 |
10 | static const INITIAL = Routes.HOME;
11 |
12 | static final routes = [
13 | GetPage(
14 | name: _Paths.HOME,
15 | page: () => const HomeView(),
16 | binding: HomeBinding(),
17 | ),
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/lib/app/routes/app_routes.dart:
--------------------------------------------------------------------------------
1 | part of 'app_pages.dart';
2 | // DO NOT EDIT. This is code generated via package:get_cli/get_cli.dart
3 |
4 | abstract class Routes {
5 | static const HOME = _Paths.HOME;
6 | }
7 |
8 | abstract class _Paths {
9 | static const HOME = '/home';
10 | }
11 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_getx_template/app/common/util/initializer.dart';
3 | import 'package:flutter_getx_template/app/routes/app_pages.dart';
4 | import 'package:get/get.dart';
5 |
6 | import 'app/modules/widgets/base_widget.dart';
7 |
8 | void main() {
9 | Initializer.init(() {
10 | runApp(const MyApp());
11 | });
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | const MyApp({Key? key}) : super(key: key);
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return ScreenUtilInit(
20 | builder: () => GetMaterialApp(
21 | title: Strings.appName,
22 | debugShowCheckedModeBanner: false,
23 | theme: AppTheme.theme,
24 | initialRoute: AppPages.INITIAL,
25 | getPages: AppPages.routes,
26 | initialBinding: InitialBindings(),
27 | builder: (_, child) => BaseWidget(
28 | child: child ?? const SizedBox.shrink(),
29 | ),
30 | ),
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_getx_template
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.12.0 <3.0.0"
22 |
23 | dependencies:
24 | flutter:
25 | sdk: flutter
26 | cupertino_icons: ^1.0.0
27 |
28 | #for dynamic ui
29 | flutter_screenutil: ^5.3.1
30 |
31 | #for state management
32 | get: ^4.6.1
33 | get_storage: ^2.0.3
34 |
35 | image_picker: ^0.8.5
36 | image_cropper: ^1.5.1
37 |
38 | #for date formatting
39 | intl: ^0.17.0
40 |
41 | octo_image: ^1.0.1
42 |
43 | dev_dependencies:
44 | flutter_test:
45 | sdk: flutter
46 |
47 | flutter_lints: ^1.0.0
48 |
49 | # For information on the generic Dart part of this file, see the
50 | # following page: https://dart.dev/tools/pub/pubspec
51 | # The following section is specific to Flutter.
52 | flutter:
53 | # The following line ensures that the Material Icons font is
54 | # included with your application, so that you can use the icons in
55 | # the material Icons class.
56 | uses-material-design: true
57 | # To add assets to your application, add an assets section, like this:
58 | assets:
59 | - assets/images/
60 | # - images/a_dot_ham.jpeg
61 | # An image asset can refer to one or more resolution-specific "variants", see
62 | # https://flutter.dev/assets-and-images/#resolution-aware.
63 | # For details regarding adding assets from package dependencies, see
64 | # https://flutter.dev/assets-and-images/#from-packages
65 | # To add custom fonts to your application, add a fonts section here,
66 | # in this "flutter" section. Each entry in this list should have a
67 | # "family" key with the font family name, and a "fonts" key with a
68 | # list giving the asset and other descriptors for the font. For
69 | # example:
70 | # fonts:
71 | # - family: Schyler
72 | # fonts:
73 | # - asset: fonts/Schyler-Regular.ttf
74 | # - asset: fonts/Schyler-Italic.ttf
75 | # style: italic
76 | # - family: Trajan Pro
77 | # fonts:
78 | # - asset: fonts/TrajanPro.ttf
79 | # - asset: fonts/TrajanPro_Bold.ttf
80 | # weight: 700
81 | #
82 | # For details regarding fonts from package dependencies,
83 | # see https://flutter.dev/custom-fonts/#from-packages
84 |
--------------------------------------------------------------------------------