Skip to content

Commit 4d2445d

Browse files
initial commit
0 parents  commit 4d2445d

File tree

89 files changed

+2099
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+2099
-0
lines changed

.gitignore

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
migrate_working_dir/
12+
13+
# IntelliJ related
14+
*.iml
15+
*.ipr
16+
*.iws
17+
.idea/
18+
19+
# The .vscode folder contains launch configuration and tasks you configure in
20+
# VS Code which you may wish to be included in version control, so this line
21+
# is commented out by default.
22+
#.vscode/
23+
24+
# Flutter/Dart/Pub related
25+
**/doc/api/
26+
**/ios/Flutter/.last_build_id
27+
.dart_tool/
28+
.flutter-plugins
29+
.flutter-plugins-dependencies
30+
.packages
31+
.pub-cache/
32+
.pub/
33+
/build/
34+
35+
# Web related
36+
lib/generated_plugin_registrant.dart
37+
38+
# Symbolication related
39+
app.*.symbols
40+
41+
# Obfuscation related
42+
app.*.map.json
43+
44+
# Android Studio will place build artifacts here
45+
/android/app/debug
46+
/android/app/profile
47+
/android/app/release
48+
*.g.dart
49+
*.config.dart
50+
pubspec.lock
51+
*.gr.dart

.metadata

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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.
5+
6+
version:
7+
revision: f1875d570e39de09040c8f79aa13cc56baab8db1
8+
channel: stable
9+
10+
project_type: app
11+
12+
# Tracks metadata for the flutter migrate command
13+
migration:
14+
platforms:
15+
- platform: root
16+
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
17+
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
18+
- platform: android
19+
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
20+
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
21+
- platform: ios
22+
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
23+
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
24+
25+
# User provided section
26+
27+
# List of Local paths (relative to this file) that should be
28+
# ignored by the migrate tool.
29+
#
30+
# Files that are not part of the templates will be ignored by default.
31+
unmanaged_files:
32+
- 'lib/main.dart'
33+
- 'ios/Runner.xcodeproj/project.pbxproj'

README.md

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Flutter app architecture
2+
3+
Model–View–ViewModel (MVVM) is a very established architectural pattern when it's come to software development. Here I have tried to put MVVM in simple example which will help you to implement in any project.
4+
5+
<p align="center">
6+
<img src="https://uploads.toptal.io/blog/image/127608/toptal-blog-image-1543413671794-80993a19fea97477524763c908b50a7a.png" />
7+
</p>
8+
9+
## Introduction
10+
11+
This sample demonstrates how one can
12+
13+
- Setup base architecture of Flutter app using Stacked plugin
14+
- Use dependency injection for layers separation
15+
- Code generator to generate boilerplate code for DI, routes and JSON parsing
16+
- Make api calls using Retrofit plugin (mostly Android developers might be familier with it).
17+
18+
Apart from the basic architecture setup, this sample also demonstrates
19+
20+
- Project folder structure
21+
- Navigation using ViewModel (without context)
22+
- Easy data sharing between the screens
23+
- And few more...
24+
25+
#### dependencies
26+
27+
- [dio](https://pub.dev/packages/dio) : http client
28+
- [retrofit](https://pub.dev/packages/retrofit) : apis
29+
- [result_monad](https://pub.dev/packages/result_monad) : Result Monad (e.g wrapping result for success and failure)
30+
- [pretty_dio_logger](https://pub.dev/packages/pretty_dio_logger) : logs network calls in a pretty, easy to read format
31+
- [stacked](https://pub.dev/packages/stacked) : mvvm plugins (viewmodels)
32+
- [auto_route](https://pub.dev/packages/auto_route) : navigation
33+
- [get_it](https://pub.dev/packages/get_it): dependency injection
34+
- [mockito](https://pub.dev/packages/mockito): unit testing
35+
36+
# Module Structure
37+
38+
<p align="center">
39+
<img src="https://camo.githubusercontent.com/a5485a38e6af7aa1055807a47e1833fc9a35eb7b997940b26936dcffae760623/68747470733a2f2f6d69726f2e6d656469756d2e636f6d2f6d61782f3737322f302a73664344456235373157442d374566502e6a7067" />
40+
</p>
41+
42+
There are 3 main modules to help separate the code. They are Data, Domain, and Application.
43+
44+
- **Data** contains Local Storage, APIs, Data objects (Request/Response object, DB objects), and the repository implementation.
45+
46+
- **Domain** contains UseCases, Domain Objects/Models, and Repository Interfaces
47+
48+
- **Application** contains UI, View Objects, Widgets, etc. Can be split into separate modules itself if needed. For example, we could have a module called Device handling things like camera, location, etc.
49+
50+
51+
# Package structure
52+
- using modular architecture to architect the app per feature to be easier and more readable and isolate the feature from each other
53+
54+
<p>
55+
<img src="https://user-images.githubusercontent.com/19567934/183311532-5efde826-f8ef-48a7-8df5-a0ed1731a2a0.png" />
56+
</p>
57+
58+
# Repository
59+
- Bridge between Data layer and Domain layer
60+
- Connects to data sources and returns mapped data
61+
- Data sources include DB and Api
62+
63+
# UseCase
64+
- Responsible for connecting to repository to retrieve necessary data. returns a Stream that will emit each update.
65+
- This is where the business logic takes place.
66+
- Returns data downstream.
67+
- Single use.
68+
- Lives in Domain (No Platform dependencies. Very testable).
69+
70+
# ViewModel
71+
- Organizes data and holds View state.
72+
- Talks to use cases.
73+
- Does not know about the View.
74+
75+
# View
76+
- Updates UI
77+
- Knows about the ViewModel
78+
- Observes changes to ViewModel.
79+
80+
# Router
81+
- I leave this open ended to suit each projects needs. The main point here is that it is important to consolidate navigation logic to one place. This helps with maintenance and unit testing.
82+
83+
## Setup
84+
85+
One can download the code in zip format or take checkout from the git repository.
86+
87+
### Note
88+
You need to run build_runner command for code generation everytime when you make changes in your original file.
89+
90+
## Todo
91+
- to add more unit tests to increase code coverage
92+
- add widget & integration testing

analysis_options.yaml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
linter:
13+
# The lint rules applied to this project can be customized in the
14+
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
15+
# included above or to enable additional rules. A list of all available lints
16+
# and their documentation is published at
17+
# https://dart-lang.github.io/linter/lints/index.html.
18+
#
19+
# Instead of disabling a lint rule for the entire project in the
20+
# section below, it can also be suppressed for a single line of code
21+
# or a specific dart file by using the `// ignore: name_of_lint` and
22+
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
23+
# producing the lint.
24+
rules:
25+
# avoid_print: false # Uncomment to disable the `avoid_print` rule
26+
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27+
28+
# Additional information about this file can be found at
29+
# https://dart.dev/guides/language/analysis-options

android/.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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+
**/*.keystore
13+
**/*.jks

android/app/build.gradle

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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 flutter.compileSdkVersion
30+
ndkVersion flutter.ndkVersion
31+
32+
compileOptions {
33+
sourceCompatibility JavaVersion.VERSION_1_8
34+
targetCompatibility JavaVersion.VERSION_1_8
35+
}
36+
37+
kotlinOptions {
38+
jvmTarget = '1.8'
39+
}
40+
41+
sourceSets {
42+
main.java.srcDirs += 'src/main/kotlin'
43+
}
44+
45+
defaultConfig {
46+
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
47+
applicationId "com.example.first_flutter_app"
48+
// You can update the following values to match your application needs.
49+
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
50+
minSdkVersion flutter.minSdkVersion
51+
targetSdkVersion flutter.targetSdkVersion
52+
versionCode flutterVersionCode.toInteger()
53+
versionName flutterVersionName
54+
}
55+
56+
buildTypes {
57+
release {
58+
// TODO: Add your own signing config for the release build.
59+
// Signing with the debug keys for now, so `flutter run --release` works.
60+
signingConfig signingConfigs.debug
61+
}
62+
}
63+
}
64+
65+
flutter {
66+
source '../..'
67+
}
68+
69+
dependencies {
70+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.example.first_flutter_app">
3+
<!-- The INTERNET permission is required for development. Specifically,
4+
the Flutter tool needs it to communicate with the running application
5+
to allow setting breakpoints, to provide hot reload, etc.
6+
-->
7+
<uses-permission android:name="android.permission.INTERNET"/>
8+
</manifest>
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.example.first_flutter_app">
3+
<application
4+
android:label="first_flutter_app"
5+
android:name="${applicationName}"
6+
android:icon="@mipmap/ic_launcher">
7+
<activity
8+
android:name=".MainActivity"
9+
android:exported="true"
10+
android:launchMode="singleTop"
11+
android:theme="@style/LaunchTheme"
12+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
13+
android:hardwareAccelerated="true"
14+
android:windowSoftInputMode="adjustResize">
15+
<!-- Specifies an Android theme to apply to this Activity as soon as
16+
the Android process has started. This theme is visible to the user
17+
while the Flutter UI initializes. After that, this theme continues
18+
to determine the Window background behind the Flutter UI. -->
19+
<meta-data
20+
android:name="io.flutter.embedding.android.NormalTheme"
21+
android:resource="@style/NormalTheme"
22+
/>
23+
<intent-filter>
24+
<action android:name="android.intent.action.MAIN"/>
25+
<category android:name="android.intent.category.LAUNCHER"/>
26+
</intent-filter>
27+
</activity>
28+
<!-- Don't delete the meta-data below.
29+
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
30+
<meta-data
31+
android:name="flutterEmbedding"
32+
android:value="2" />
33+
</application>
34+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.example.first_flutter_app
2+
3+
import io.flutter.embedding.android.FlutterActivity
4+
5+
class MainActivity: FlutterActivity() {
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Modify this file to customize your launch splash screen -->
3+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4+
<item android:drawable="?android:colorBackground" />
5+
6+
<!-- You can insert your own image assets here -->
7+
<!-- <item>
8+
<bitmap
9+
android:gravity="center"
10+
android:src="@mipmap/launch_image" />
11+
</item> -->
12+
</layer-list>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Modify this file to customize your launch splash screen -->
3+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4+
<item android:drawable="@android:color/white" />
5+
6+
<!-- You can insert your own image assets here -->
7+
<!-- <item>
8+
<bitmap
9+
android:gravity="center"
10+
android:src="@mipmap/launch_image" />
11+
</item> -->
12+
</layer-list>
Loading
Loading
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
4+
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
5+
<!-- Show a splash screen on the activity. Automatically removed when
6+
the Flutter engine draws its first frame -->
7+
<item name="android:windowBackground">@drawable/launch_background</item>
8+
</style>
9+
<!-- Theme applied to the Android Window as soon as the process has started.
10+
This theme determines the color of the Android Window while your
11+
Flutter UI initializes, as well as behind your Flutter UI while its
12+
running.
13+
14+
This Theme is only used starting with V2 of Flutter's Android embedding. -->
15+
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
16+
<item name="android:windowBackground">?android:colorBackground</item>
17+
</style>
18+
</resources>

0 commit comments

Comments
 (0)