Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Overview of Flutter and its key features
Flutter is an open-source UI framework developed by Google for building natively compiled applications for mobile, web, and desktop platforms using a single codebase. It provides a fast and efficient way to create visually appealing and high-performance applications with a consistent user experience across different platforms.
Create form screen using digit_components
This document provides details about creation of a form screen using the official digit_components pub package
Install and setup flutter in our local machine
Create a flutter project
flutter create project_name
Build a form using the digit_components: ^latest_version
In pubspec.yaml add the digit_components and reactive_forms under dependencies
Follow the example file to start with the Reactive forms.
1. Hot Reload: Flutter's hot reload feature allows developers to see instant updates to the UI during development. It significantly speeds up the development process, enabling developers to experiment, iterate, and refine their app's UI and functionality in real-time.
2. Single Codebase: One of the key advantages of Flutter is the ability to write code once and deploy it on multiple platforms. With a single codebase, developers can build applications for Android, iOS, web, and desktop platforms, reducing development time and effort.
3. Expressive UI: Flutter offers a rich set of customizable widgets that allow developers to create beautiful and responsive user interfaces. These widgets are designed to adapt to different screen sizes and form factors, providing a consistent look and feel across platforms.
4. Fast Performance: Flutter's performance is comparable to native applications as it uses Dart, a compiled language, and leverages the Skia graphics library. Flutter apps are compiled to highly efficient native code, ensuring smooth animations, fast startup times, and excellent overall performance.
5. Access to Native Features: Flutter provides direct access to native device features and APIs, enabling developers to utilize platform-specific capabilities. Whether it's accessing device sensors, camera, geolocation, or integrating with platform-specific services, Flutter makes it easy to leverage native functionality.
6. Rich Ecosystem: Flutter has a vibrant ecosystem with a wide range of packages and plugins available through the Flutter Package Manager (pub.dev). These packages extend the functionality of Flutter and offer pre-built solutions for common app requirements, saving development time and effort.
At the core of Flutter's architecture is the Flutter engine, which is written in C++ and provides low-level rendering capabilities. The engine interfaces with the host operating system and handles tasks such as layout, drawing, and gesture recognition.
On top of the engine, Flutter provides a comprehensive UI toolkit that consists of widgets. Widgets are the building blocks of Flutter applications and represent different elements of the user interface.
Flutter's reactive framework allows widgets to rebuild efficiently when there are changes
Watch the video here to understand Flutter Architecture -
Flutter Installation and setup guide
Setting up device emulators/simulators for testing
Digit UI Flutter Development Guide
Once the development environment setup is completed, we have to run the application locally. This document provides steps on how to run the works_shg_app on a local device.
Clone the repo https://github.com/egovernments/DIGIT-Works
git clone https://github.com/egovernments/DIGIT-Works.git
To run the application in the local environment, add the .env
file in the root folder of the project (frontend/works_shg_app
)-
Sample .env config:
BASE_URL='https://works-dev.digit.org/'
MDMS_API_PATH='egov-mds-service/v1/_search'
GLOBAL_ASSETS='https://works-dev.digit.org/works-dev-asset/worksGlobalConfig.json'
ENV_NAME="DEV"
Run the below commands in your terminal from the root of the project (frontend/works_shg_app)
flutter clean: To clean the build cache.
flutter pub get: To install the dependencies packages
Enable the desired device or browser to run the application using the command - flutter run: To start the application
Access the Flutter development tools for debugging purposes from the link in the terminal.
Prior knowledge of Flutter
Prior knowledge of Dart language
Prior knowledge of State management
Prior knowledge of pub dev packages
Prior knowledge of Git
Prior knowledge of HTTP client request calls
Knowledge of the DIGIT Flutter UI framework
Check the page to access help documents on the tools required for UI development.
BLoC State Management with Bloc Consumer, Bloc Provider, and Bloc Listener
BLoC (Business Logic Component) is a state management pattern in Flutter that helps separate the business logic from the UI.
It follows a unidirectional data flow, where the UI interacts with the BLoC to trigger events, and the BLoC emits new states that the UI can react to. In addition to the core BLoC pattern, the Flutter BLoC library provides useful widgets such as Bloc Consumer, Bloc Provider, and Bloc Listener to simplify the integration of BLoC in Flutter applications.
BLoC: The Business Logic Component represents the core logic of your application. It manages the state and exposes streams or methods to interact with that state.
Event: An event is a user action or an external trigger that is passed to the BLoC. It can trigger state changes or other operations in the BLoC.
State: The state represents the current condition of the application. It is emitted by the BLoC in response to events and reflects the data that the UI needs to display or react to.
The BlocConsumer
widget is a powerful tool for consuming the state emitted by a BLoC and rebuilding specific parts of the UI when the state changes.
Wrap the portion of your widget tree that depends on the BLoC state with the BlocConsumer
widget.
Provide the BLoC instance and a builder function to define how the UI should be rebuilt based on the emitted state.
Inside the builder function, access the state and return the corresponding widget or widgets.
The listener
parameter can be used to perform side effects and function calls based on the emitted state, such as showing a toast message or navigating to a different screen.
The BlocProvider
widget is responsible for providing the BLoC instance to the widget tree and ensuring that it's accessible to all descendant widgets.
Wrap the root of your widget tree with BlocProvider
.
Specify the BLoC type using the create
parameter to create a new instance of the BLoC.
Access the BLoC instance using BlocProvider.of<BlocType>(context)
within descendant widgets.
The BlocListener
widget is useful for listening to state changes emitted by the BLoC and performing side effects without rebuilding the UI.
Wrap the BlocListener
widget around the portion of the widget tree that needs to listen to state changes.
Provide the BLoC instance and a listener function to handle state changes.
For more information on Bloc Pattern, navigate through the below reference links -
Different types of state management in Flutter with Provider and Bloc
Two popular state management approaches in Flutter are Provider and BLoC (Business Logic component). This documentation provides an overview of these state management techniques, their key concepts, and how to implement them in Flutter applications.
Provider: A simplified State Management Solution
State management involves managing and updating the data and UI state within a Flutter application. It helps handle dynamic data, respond to user interactions, and keep the user interface synchronized with the underlying data.
Pre -requirements for publishing the app bundle to play store
This page provides the requirements that should be met to publish the app bundle to Google Play Store.
Before publishing an app bundle to the Google Play Store, ensure that the following requirements are met:
App Content and Policies:
Ensure the app complies with Google Play Store policies, including content guidelines, restricted content, and advertising policies.
Ensure the app's content does not infringe on intellectual property rights or violate any legal restrictions.
Privacy and Data Handling:
Implement appropriate privacy measures to protect user data and comply with privacy regulations (e.g., GDPR).
Communicate your app's data handling practices and obtain user consent when necessary.
Have Terms & Conditions and Privacy documents handy
Write an engaging and informative app description that accurately represents your app's functionality and benefits.
Choose relevant and compelling promotional graphics, including an app icon and feature graphic.
Store Policies and Agreements:
Review and accept the Google Play Developer Distribution Agreement.
Familiarize yourself with the Google Play Store policies and ensure your app complies with them.
Developer Account: Create a Google Play Developer account and complete the registration process
Distribution:
Choose the appropriate pricing and distribution options for your app, such as free, paid, or freemium models.
Select the countries or regions where you want to make your app available.
Release Management:
Consider using the Google Play Console's release management tools to monitor and control your app's releases.
Remember to carefully review the Google Play Store's guidelines, documentation, and recommendations for publishing apps to ensure a smooth and successful deployment process.
Steps to generate APKs and App bundles for Android applications
Follow the steps on this page to build the APK and IPA for deploying in Play Store and App-store.
Follow the Flutter Installation and setup Guide and Run the Application till the Flutter pub is set up.
Run the below command in your terminal from theroot of the project to generate the APK
flutter build apk --release
Prior knowledge of generating unique key store files for your application ( Reference links: Generating key store for your Android application)
Changing the App name
Changing App Logo (Ref Link: Changing app logo in Flutter)
Prior knowledge of app bundle creation for publishing in the Play Store
Terms and Conditions and Privacy Documents for your application
Note: The generated key store file needs to be added to the Android/app folder of your project. This is needed for publishing the next version of your application.
Add a key.properties file inside your Android folder which is a reference to your key store file. Below is the sample key.properties file.
Run the below command in your terminal from the root of the project to generate the App bundle to publish in the play store.
flutter build app bundle
This page runs you through the steps to build the web application and deploy in respective environment.
Follow the instructions to set up the job pipeline. Ignore the steps not applicable to the front end.
Instructions here are provided assuming CD/CI has been set up using the DIGIT ci-as-code module.
Before setting up the job pipeline, make sure each project has a docker folder in the root folder of the project. The cirrusci flutter docker tag must be mentioned for building the application through Jenkins. Check the image below for reference.
The global assets inside the .env file should be loaded from the environment assets.
Note: The global assets file needs to be in JSON format for Flutter
Follow the sample config added in yaml files of the respective environment to load the global assets of works_shg_app.
dev yaml file :
Congrats!!! We are now ready to build and deploy the application on the web.
Go to the Jenkins page. Click on your project to build under the folder path mentioned below.
For reference, if works_shg_app need to be build, Go to path
Go to the Jenkins page. Click on the desired environment you want to deploy the build
Path ref:
Coding conventions and style guidelines help ensure that the codebase follows a consistent and readable structure. Consistency improves code collaboration, readability, and maintainability.
Use camelCase for variable and function names. Start with a lowercase letter.
Use PascalCase for class and enum names. Start with an uppercase letter.
Use lowercase_with_underscores for constant names and file names.
Use kebab-case for folder names
Avoid using acronyms or abbreviations in names unless they are widely known.
Use the Dart formatter (dartfmt
) to automatically format code according to the Flutter style guide.
Indent code with 2 spaces.
Place a single space before and after binary operators.
Use a single blank line to separate logical sections of code.
Write tests for critical functionality and complex logic using the Flutter testing framework.
Organize tests into separate files following the same package structure as the production code.
Name test files with the component_test.dart
suffix.
Use descriptive names for test cases and individual tests.
Use descriptive variable, function, and class names instead of relying heavily on comments.
Write clear and concise comments that explain the intent and purpose of the code.
Use comments sparingly and only when necessary to clarify complex or non-obvious logic.
Document public APIs, classes, and functions using Dartdoc-style comments
Place assets, such as images and fonts, in the assets
directory and specify them in the pubspec.yaml
file.
Use relative paths for referencing assets within the code.
Handling common issues and errors
Dependency Conflicts: Check for conflicting versions of dependencies in your pubspec.yaml
file and resolve them by specifying compatible versions.
Missing or Incorrect Imports: Verify that all necessary packages are imported correctly. Check for typos or missing package names.
Widget Rendering Issues: Debug issues related to widget rendering by checking the widget tree, examining layout constraints, or identifying invalid or conflicting widget properties.
Logging: Use print statements or logging libraries like logger
or flutter_logger
to log important information during development.
Debugging Tools: Utilize Flutter's debugging tools such as the Flutter DevTools, which provide insights into the app's performance, UI layout, and network requests. Use breakpoints to pause execution at specific lines of code for closer inspection.
Try-Catch Statements: Surround code that may throw exceptions with a try-catch block to handle anticipated errors gracefully. Use the catch block to provide appropriate error messages or perform recovery actions.
Null Safety: Embrace Flutter's null safety feature to catch and handle null-related errors at compile time. Use the ?
and !
operators to handle nullable variables and avoid null-related runtime errors.
Install Flutter on your device
After installation of Flutter, to check the installed version, use the command flutter --version
Note: Version might vary based on the current version used in the project
Run the Flutter Doctor command once the Flutter is installed. The Flutter Doctor performs the following tasks:
Downloads missing files required by the development environment.
Ensures we’ve installed the following:
Android SDK
Apple Xcode (on Mac)
Ensures that we’ve agreed to all software development licenses.
Checks the Android Studio IDE setup and recommends any changes required to get it working with Flutter.
Checks for connected devices.
Verifies that Flutter can recognize any connected hardware devices.
Recommends any changes required to get them connected and working.
Outputs a diagnosis, listing out issues found and recommendations.
If you want to run in local Chrome, make sure web security is disabled to avoid CORS errors.
Find below the steps to disable the web security of Chrome
Go to the folder where your flutter is added--flutter\bin\cache and remove a file named: flutter_tools.stamp
Go to flutter\packages\flutter_tools\lib\src\web and open the file chrome.dart.
Find '--disable-extensions'
Add '--disable-web-security'
Provider: a simplified state management solution
Provider is a Flutter package that simplifies state management by offering a straightforward approach based on the InheritedWidget mechanism. It allows data to be passed down the widget tree efficiently and notifies dependent widgets when the data changes.
ChangeNotifier: A class that extends ChangeNotifier
and represents the state. It provides the notifyListeners()
method to notify listeners about state changes.
Provider: An InheritedWidget that provides the state to its descendants. It listens to ChangeNotifier
updates and rebuilds widgets that depend on the state.
Add the provider
package to your Flutter project's dependencies.
Create a class that extends ChangeNotifier
to represent the state.
Wrap the root widget of your application with the MultiProvider
widget to establish the provider hierarchy.
Within the widget tree, use Provider.of<T>(context)
to access the state and rebuild widgets when the state changes.
Use Consumer<T>
to consume the state and rebuild specific widgets when the state changes.
ChangeNotifier classes are responsible for holding the application state and notifying listeners about state changes. To update the state, modify the properties of the ChangeNotifier subclass and call notifyListeners()
.
Use Provider.of<T>(context)
to obtain the current state within a widget. It rebuilds the widget whenever the state changes.
Use Consumer<T>
to listen to changes in the state and rebuild only the specific subtree wrapped by the Consumer
widget.
For detailed information on Provider, navigate through the below reference links: