Hi readers, I'm kinda excited to share you the journey when I build a simple app using Flutter. So, recently this week I received an assignment to build an app that help us to explore PS5 games. Then we will name it "Game Center" App. Before we start, I made some important points that will guide the development process:
- Looking for UI/UX Ideas
- Toolkit & External libraries
- Clean and Complete architecture
- Start Developing the module
- Build and deploy Apps
Ok, I think that's enough as an introduction, now without any further ado lets start our journey guys!
This part is quite challenging for me because I am not an artist, but I have idealism to try to get the perfect design even if it doesn't exist. So to save time, I made a quick selection of dribbble:
Preview 1 | Preview 2 |
---|---|
I like the first design, but the dark theme seems more suitable for game center app. So, mixing them will be cool.
Mixed |
---|
We must prepare the toolkit and determine which external library to use. Here are the toolkit and SDK that I'm using in this assignment:
- Macbook Pro M1 2020
- Flutter Version Manager (FVM) + Sidekick GUI
- Flutter 3.3.1
- Latest Android Studio
- Latest Visual Code Insider with Extensions:
- Awesome Flutter Snippets
- bloc (required)
- change-case
- Dart (required)
- Flutter (required)
- Flutter Helpers
- Dart Barrels Generator
- GitLens — Git supercharged
- Pubspec Assist
- Todo Tree
For external libraries, I determine based on the needs of the use case only. Such as:
- auto_route -> A routing solution that helps us generate navigation automatically. The generated route can also be useful for Robust, clean and easier Deeplink navigation
- alice -> Http traffic observer, debugging made easily
- cached_network_image -> To load and cache network images
- catcher -> Error catcher handler, it allows us to manage errors even integrate them into firebase crashlytics easily.
- dio -> A powerful Http client for Dart,
- dio_cache_interceptor -> to cache the responses from [dio] automatically. It has many cache strategy,
- easy_localization && easy_localization_loader -> Easy and Fast internationalizing and localization for Flutter Apps
- envied -> Convert Environment variable to dart. This is a good and safe way to store env in our apps
- equatable -> to Simplify Equality Comparisons
- flutter_bloc -> Our main state management. I love using bloc and this help me a lot to develop great app
- fluttertoast -> to show native toast message
- google_fonts -> Use google font without import font files manually
- infinite_scroll_pagination -> Lazily load and display pages of items as the user scrolls down our screen. I will integrate this with Bloc.
- injectable -> to generate dependency injection using annotation
- json_annotation & json_serializable -> Data Model class generator that help us to generate a robust and clean model.
- shimmer -> Skeleton loader to create beautiful loading
- photo_view -> Interactive images viewer
- hive_flutter -> No Sql storage to keep errorlytics data
- flutter_markdown -> To preview markdown format
Seems like a lot, right? Don't worry, we will wrap most of them so we can just change the library without affecting the results.
We will implement business requirements in a maintainable, scalable and testable manner. So we need to have a clean architecture that can suit our needs.
Since we use BLoC as the main state management that manages User Interface changes based on the existing state. There are several terms and components used in the application of the BLoC Pattern:
- Event is the input for BLoC. Typically, keypress events or any commands to load data.
- State The screen will be adjusted based on the state generated from the BLoC.
- Transition is a state that changes when the event is received and before the state is updated.
- Bloc is the main component that sets the Events process to State. Our logic will be put in here.
To support the application of BLOC, we need to use the BloC Pattern which consists of 3 main layers that are interconnected. This pattern will also have an influence on the project architecture used.
- Layer 1: User Interface, The layer that contains all the UI components or what we call “widgets”. This component can be seen and interacted with by the user, for example a button, form or other clickable object.
- Layer 2: BLoC or Cubit, This layer will be handling our business logic. It will act as a controller between UI and the data layers. E.g, email and password validation logic will be written here.
- Layer 3: Repository, This layer will make requests to the Backend or manage data on local storage. Sqlite, hive, or Restful API will be held here..
├──_localization_gen/
├──assets/
│ ├──images/
│ ├──localizations/
├──lib/
│ ├──config/
│ │ ├──injectable/
│ │ ├──routes/
│ │ ├──themes/
│ ├──constant/
│ ├──core/
│ │ ├──language/
│ │ ├──theme/
│ │ ├──errlytics/
│ │ ├──app_setting.dart
│ ├──env/
│ ├──modules/
│ ├──utils/
│ │ ├──helpers/
│ │ ├──services/
│ │ │ ├──rest_api_service/
│ │ │ ├──native_api_service.dart
│ ├──widgets/
│ │ ├──design_system/
│ │ ├──main.dart
│ │ ├──main.extend.dart
│ │ ├──main.library.dart
│ │ ├──main.import.dart
├──.env.*
├──analysis_options.yaml
├──build.yaml
├──pubspec.yaml
├──start_unix.sh
The architectural design of the project is adjusted to the needs of our app and the BLoC Pattern used to get a clean architecture. Here's a detailed explanation:
├──assets/
├──images/
→ any images such as icons, illustrations, and logo├──localizations/
→ all supported language localization file in .json format
|──config/
|──injectable/
→ contains generated and initialization of dependency injection file├──routes/
→ routes configuration , auth guard and generated routes file├──themes/
→ theme configuration and color palette constant. Dark & Light
|──constant/
→ any related constant for API endpoint path, custom icons data, error codes, generated localizations key, and assets path.├──core/
├──language/
→ Language module├──theme/
→ Theme module├──errlytics/
→ Alice and Errorlytics Observer module├──app_setting.dart
→ Configuration for base url API, default theme, supported language, logs flag, and so on
├──env/
→ selected and generated environment data from .env files├──modules/
→ Main modules that contain related UI components, bloc, providers and repository. For e.g, profile, home, transaction├──utils/
├──helpers/
→ any reusable general helper class such as online connection checker, money or time formatting, and so on├──services/
├──rest_api_service/
→ restful API class handler├──native_api_service.dart
→ Class definition to generate dependency injection for any plugin we use.
widgets/
→ All reusable widgets├──design_system/
→ Reusable Design system widgets to reduce boiler plate
sh start_unix.sh/
→ A generator script before build this app, runsh start_unix.sh -h
for available commands
- Run
sh start_unix.sh -x
int the root of project - Run
flutter build apk
to build apk - Run
flutter run
to run apk - If you are using Visual Code, just use F5 shortcut to run and debug app
in case you just want to try the app, please download apk here https://github.com/ariefwijaya/game_center/releases/tag/v1.0.0
Screen.Recording.2022-10-25.at.09.21.52.mp4
Splash | Onboarding | Home | Filter |
---|---|---|---|
Search | Detail 1 | Detail 2 | ErrorLytics | Alice |
---|---|---|---|---|