├── .gradle ├── 5.2.1 │ ├── gc.properties │ ├── fileChanges │ │ └── last-build.bin │ └── fileHashes │ │ └── fileHashes.lock ├── vcs-1 │ └── gc.properties └── buildOutputCleanup │ ├── cache.properties │ └── buildOutputCleanup.lock ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj └── .gitignore ├── assets ├── images │ └── waiting.png └── fonts │ ├── OpenSans-Bold.ttf │ ├── Quicksand-Bold.ttf │ ├── OpenSans-Regular.ttf │ ├── Quicksand-Light.ttf │ ├── Quicksand-Medium.ttf │ └── Quicksand-Regular.ttf ├── android ├── gradle.properties ├── .gitignore ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── 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 │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ └── values │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── codingwithmitch │ │ │ │ │ └── firstflutterapp │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ └── Test.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── .metadata ├── lib ├── models │ └── transaction.dart ├── styles.dart ├── widgets │ ├── chart_bar.dart │ ├── chart.dart │ ├── transaction_list.dart │ └── new_transaction.dart └── main.dart ├── .gitignore ├── test └── widget_test.dart ├── pubspec.yaml ├── pubspec.lock └── README.md /.gradle/5.2.1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/5.2.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Tue Jun 02 13:25:25 PDT 2020 2 | gradle.version=5.2.1 3 | -------------------------------------------------------------------------------- /assets/images/waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/images/waiting.png -------------------------------------------------------------------------------- /assets/fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/Quicksand-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/Quicksand-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/Quicksand-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/Quicksand-Light.ttf -------------------------------------------------------------------------------- /assets/fonts/Quicksand-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/Quicksand-Medium.ttf -------------------------------------------------------------------------------- /assets/fonts/Quicksand-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/assets/fonts/Quicksand-Regular.ttf -------------------------------------------------------------------------------- /.gradle/5.2.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/.gradle/5.2.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/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/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FlutterPlayground/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/codingwithmitch/firstflutterapp/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.codingwithmitch.firstflutterapp 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | 7 | 8 | 9 | } 10 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.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/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.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: 5f21edf8b66e31a39133177319414395cc5b5f48 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/models/transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | class Transaction{ 4 | 5 | final String id; 6 | final String title; 7 | final double amount; 8 | final DateTime date; 9 | 10 | Transaction({ 11 | @required this.id, 12 | @required this.title, 13 | @required this.amount, 14 | @required this.date 15 | }); 16 | 17 | } 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lib/styles.dart: -------------------------------------------------------------------------------- 1 | const LargeTextSize = 22.0; 2 | const MediumTextSize = 16.0; 3 | const SmallTextSize = 12.0; 4 | 5 | const DefaultMargin = 16.0; 6 | const DefaultPadding = 16.0; 7 | 8 | const DefaultCardMargin = 10.0; 9 | const hCardMargin = 15.0; 10 | const vCardMargin = 10.0; 11 | 12 | const DefaultCardPadding = 10.0; 13 | const hCardPadding = 10.0; 14 | const vCardPadding = 10.0; 15 | 16 | const DefaultCardElevation = 5.0; 17 | 18 | const DefaultBorderWidth = 2.0; 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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/.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 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | include ':app' 6 | 7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 8 | def properties = new Properties() 9 | 10 | assert localPropertiesFile.exists() 11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 12 | 13 | def flutterSdkPath = properties.getProperty("flutter.sdk") 14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 16 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Exceptions to above rules. 43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 44 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:firstflutterapp/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/codingwithmitch/firstflutterapp/Test.kt: -------------------------------------------------------------------------------- 1 | package com.codingwithmitch.firstflutterapp 2 | 3 | const val QUESTION: String = "question" 4 | const val ANSWERS: String = "answer" 5 | 6 | class Test{ 7 | 8 | var total: Int = 0 9 | 10 | fun add(value: Int){ 11 | total += value 12 | println(total) 13 | } 14 | 15 | fun doThing(function: () -> Unit){ 16 | function() 17 | } 18 | 19 | fun main(){ 20 | 21 | doThing {add(2)} 22 | 23 | 24 | // val answersMap: Array> = arrayOf( 25 | // mapOf( 26 | // QUESTION to "Is Florian really my son?", 27 | // ANSWERS to arrayOf("yes", "no") 28 | // ), 29 | // mapOf( 30 | // QUESTION to "Who's your favorite android teacher?", 31 | // ANSWERS to arrayOf("Coding with Mitch", "Coding In Flow", "Donn Felker", "Nate Ebel") 32 | // ) 33 | // ) 34 | // 35 | // 36 | // val answers: Array = answersMap[0][ANSWERS] as Array 37 | // 38 | // for(answer in answers){ 39 | // println(answer) 40 | // } 41 | } 42 | 43 | 44 | 45 | 46 | } -------------------------------------------------------------------------------- /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 | firstflutterapp 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 | -------------------------------------------------------------------------------- /lib/widgets/chart_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ChartBar extends StatelessWidget { 4 | 5 | final String _label; 6 | final double _spendingAmount; 7 | final double _spendingPctOfTotal; 8 | 9 | ChartBar(this._label, this._spendingAmount, this._spendingPctOfTotal); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Column( 14 | children: [ 15 | Container( 16 | height: 20, 17 | child: FittedBox( 18 | child: Text("\$${_spendingAmount.toStringAsFixed(0)}"), 19 | ), 20 | ), 21 | SizedBox(height: 4,), 22 | Container( 23 | height: 60, 24 | width: 10, 25 | child: Stack( 26 | children: [ 27 | Container( 28 | decoration: BoxDecoration( 29 | border: Border.all(color: Colors.grey, width: 1.0), 30 | color: Color.fromRGBO(220, 220, 220, 1), 31 | borderRadius: BorderRadius.circular(10), 32 | ), 33 | ), 34 | FractionallySizedBox( 35 | heightFactor: _spendingPctOfTotal, 36 | child: Container( 37 | decoration: BoxDecoration( 38 | color: Theme.of(context).primaryColor, 39 | borderRadius: BorderRadius.circular(10), 40 | ), 41 | ), 42 | ) 43 | ], 44 | ), 45 | ), 46 | SizedBox(height: 4,), 47 | Text(_label), 48 | ], 49 | ); 50 | } 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /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 28 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.codingwithmitch.firstflutterapp" 42 | minSdkVersion 16 43 | targetSdkVersion 28 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 | -------------------------------------------------------------------------------- /lib/widgets/chart.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:firstflutterapp/widgets/chart_bar.dart'; 4 | import 'package:firstflutterapp/models/transaction.dart'; 5 | import 'package:intl/intl.dart'; 6 | 7 | class Chart extends StatelessWidget { 8 | 9 | final List _recentTransactions; 10 | 11 | Chart(this._recentTransactions); 12 | 13 | List> get groupedTransactionValues{ 14 | return List.generate(7, (index) { 15 | final weekDay = DateTime.now().subtract(Duration(days: index),); 16 | double totalSum = 0.0; 17 | for(var i = 0; i < _recentTransactions.length - 1; i++){ 18 | if(_recentTransactions[i].date.day == weekDay.day 19 | && _recentTransactions[i].date.month == weekDay.month 20 | && _recentTransactions[i].date.year == weekDay.year){ 21 | totalSum += _recentTransactions[i].amount; 22 | } 23 | } 24 | return { 25 | "day": DateFormat.E().format(weekDay).substring(0, 3), 26 | "amount": totalSum 27 | }; 28 | }).reversed.toList(); 29 | } 30 | 31 | double get totalSpending{ 32 | return groupedTransactionValues.fold(0.0, (previousValue, listElement) { 33 | return previousValue + listElement["amount"]; 34 | }); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return totalSpending == 0.0 ? SizedBox(height: 10) : Card( 40 | elevation: 6, 41 | margin: EdgeInsets.all(20), 42 | child: Container( 43 | padding: EdgeInsets.all(10), 44 | child: Row( 45 | mainAxisAlignment: MainAxisAlignment.spaceAround, 46 | children: groupedTransactionValues.map((data) { 47 | return Flexible( 48 | fit: FlexFit.tight, 49 | child: ChartBar( 50 | data["day"], 51 | data["amount"], 52 | ((data["amount"] as double) / totalSpending) 53 | ), 54 | ); 55 | }).toList(), 56 | ), 57 | ), 58 | ); 59 | } 60 | } 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/widgets/transaction_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:intl/intl.dart'; 3 | 4 | import '../models/transaction.dart'; 5 | 6 | class TransactionList extends StatelessWidget { 7 | 8 | final List _userTransactions; 9 | final Function _deleteTransaction; 10 | 11 | TransactionList(this._userTransactions, this._deleteTransaction); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | alignment: Alignment.center, 17 | child: _userTransactions.isEmpty ? Column( 18 | children: [ 19 | Text( 20 | "No transactions added yet!", 21 | style: Theme.of(context).textTheme.headline6, 22 | ), 23 | SizedBox(height: 20,), 24 | Container( 25 | child: Image.asset( 26 | "assets/images/waiting.png", 27 | fit: BoxFit.cover, 28 | ), 29 | height: 200, 30 | ), 31 | ] 32 | ) : ListView.builder( 33 | itemBuilder: (ctx, index) { 34 | return Card( 35 | elevation: 6, 36 | margin: EdgeInsets.symmetric(vertical: 8, horizontal: 5), 37 | child: ListTile( 38 | leading: CircleAvatar( 39 | radius: 30, 40 | child: Padding( 41 | padding: EdgeInsets.all(6), 42 | child: FittedBox( 43 | child: Text( 44 | "\$${_userTransactions[index].amount.toStringAsFixed(2)}" 45 | ), 46 | ), 47 | ), 48 | ), 49 | title: Text( 50 | _userTransactions[index].title, 51 | style: Theme.of(context).textTheme.headline6, 52 | ), 53 | subtitle: Text( 54 | DateFormat.yMMMd().format(_userTransactions[index].date), 55 | ), 56 | trailing: IconButton( 57 | icon: Icon(Icons.delete), 58 | color: Theme.of(context).errorColor, 59 | onPressed: () { 60 | _deleteTransaction(_userTransactions[index].id); 61 | }, 62 | ), 63 | ), 64 | ); 65 | }, 66 | itemCount: _userTransactions.length, 67 | ), 68 | ); 69 | } 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: firstflutterapp 2 | description: My first flutter app 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.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | intl: ^0.16.1 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^0.1.3 31 | 32 | dev_dependencies: 33 | flutter_test: 34 | sdk: flutter 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | 47 | # To add assets to your application, add an assets section, like this: 48 | assets: 49 | - assets/images/waiting.png 50 | 51 | # An image asset can refer to one or more resolution-specific "variants", see 52 | # https://flutter.dev/assets-and-images/#resolution-aware. 53 | 54 | # For details regarding adding assets from package dependencies, see 55 | # https://flutter.dev/assets-and-images/#from-packages 56 | 57 | # To add custom fonts to your application, add a fonts section here, 58 | # in this "flutter" section. Each entry in this list should have a 59 | # "family" key with the font family name, and a "fonts" key with a 60 | # list giving the asset and other descriptors for the font. For 61 | # example: 62 | fonts: 63 | - family: OpenSans 64 | fonts: 65 | - asset: assets/fonts/OpenSans-Bold.ttf 66 | weight: 700 67 | - asset: assets/fonts/OpenSans-Regular.ttf 68 | - family: Quicksand 69 | fonts: 70 | - asset: assets/fonts/Quicksand-Bold.ttf 71 | weight: 700 72 | - asset: assets/fonts/Quicksand-Light.ttf 73 | - asset: assets/fonts/Quicksand-Medium.ttf 74 | - asset: assets/fonts/Quicksand-Regular.ttf 75 | 76 | # - family: Schyler 77 | # fonts: 78 | # - asset: fonts/Schyler-Regular.ttf 79 | # - asset: fonts/Schyler-Italic.ttf 80 | # style: italic 81 | # - family: Trajan Pro 82 | # fonts: 83 | # - asset: fonts/TrajanPro.ttf 84 | # - asset: fonts/TrajanPro_Bold.ttf 85 | # weight: 700 86 | # 87 | # For details regarding fonts from package dependencies, 88 | # see https://flutter.dev/custom-fonts/#from-packages 89 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/widgets/new_transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:intl/intl.dart'; 3 | 4 | import '../styles.dart'; 5 | 6 | class NewTransaction extends StatefulWidget { 7 | 8 | final Function _addNewTx; 9 | 10 | NewTransaction(this._addNewTx); 11 | 12 | @override 13 | _NewTransactionState createState() => _NewTransactionState(); 14 | } 15 | 16 | class _NewTransactionState extends State { 17 | 18 | final _titleController = TextEditingController(); 19 | final _amountController = TextEditingController(); 20 | DateTime _selectedDate; 21 | 22 | _presentDatePicker(BuildContext ctx){ 23 | showDatePicker( 24 | context: ctx, 25 | initialDate: DateTime.now(), 26 | firstDate: DateTime(2019), 27 | lastDate: DateTime.now() 28 | ).then((pickedDate) { 29 | if(pickedDate == null){ 30 | return; 31 | } 32 | setState(() { 33 | _selectedDate = pickedDate; 34 | }); 35 | }); 36 | } 37 | 38 | _submitData(){ 39 | if(_amountController.text.isEmpty){ 40 | return; 41 | } 42 | final enteredTitle = _titleController.text; 43 | if(_amountController.text.isEmpty){ 44 | return; 45 | } 46 | final enteredAmount = double.parse(_amountController.text); 47 | if(enteredTitle.isEmpty || enteredAmount <= 0 || _selectedDate == null){ 48 | return; 49 | } 50 | widget._addNewTx(enteredTitle, enteredAmount, _selectedDate); 51 | Navigator.of(context).pop(); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return Card( 57 | elevation: DefaultCardElevation, 58 | child: Container( 59 | padding: EdgeInsets.all(DefaultCardPadding), 60 | child: Column( 61 | crossAxisAlignment: CrossAxisAlignment.end, 62 | children: [ 63 | TextField( 64 | controller: _titleController, 65 | decoration: InputDecoration( 66 | labelText: "Title", 67 | ), 68 | onSubmitted: (_) => _submitData(), 69 | ), 70 | TextField( 71 | controller: _amountController, 72 | decoration: InputDecoration( 73 | labelText: "Amount", 74 | ), 75 | keyboardType: TextInputType.numberWithOptions(decimal: true), 76 | onSubmitted: (_) => _submitData(), 77 | ), 78 | Container( 79 | height: 70, 80 | child: Row( 81 | children: [ 82 | Expanded( 83 | child: Text( 84 | _selectedDate == null ? "No Date Chosen!" : DateFormat.yMMMd().format(_selectedDate), 85 | ), 86 | ), 87 | FlatButton( 88 | textColor: Theme.of(context).primaryColor, 89 | child: Text( 90 | "Choose Date", 91 | style: TextStyle(fontWeight: FontWeight.bold), 92 | ), 93 | onPressed: () { 94 | _presentDatePicker(context); 95 | }, 96 | ) 97 | ], 98 | ), 99 | ), 100 | RaisedButton( 101 | color: Theme.of(context).primaryColor, 102 | child: Text("Add Transaction"), 103 | onPressed: (){ 104 | _submitData(); 105 | }, 106 | textColor: Theme.of(context).textTheme.button.color, 107 | ) 108 | ], 109 | ), 110 | ) 111 | ); 112 | } 113 | } 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'models/transaction.dart'; 4 | import 'package:firstflutterapp/widgets/chart.dart'; 5 | import 'package:firstflutterapp/widgets/new_transaction.dart'; 6 | import 'package:firstflutterapp/widgets/transaction_list.dart'; 7 | import 'styles.dart'; 8 | 9 | void main() => runApp(MyApp()); 10 | 11 | class MyApp extends StatefulWidget { 12 | 13 | @override 14 | _MyAppState createState() => _MyAppState(); 15 | } 16 | 17 | class _MyAppState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | title: "Personal Expenses", 22 | theme: ThemeData( 23 | primarySwatch: Colors.purple, 24 | accentColor: Colors.amber, 25 | errorColor: Colors.red, 26 | fontFamily: "Quicksand", 27 | textTheme: ThemeData.light().textTheme.copyWith( 28 | headline6: TextStyle( 29 | fontFamily: "OpenSans", 30 | fontSize: 17, 31 | fontWeight: FontWeight.bold, 32 | ), 33 | button: TextStyle( 34 | color: Colors.white 35 | ) 36 | ), 37 | appBarTheme: AppBarTheme( 38 | textTheme: ThemeData.light().textTheme.copyWith( 39 | headline6: TextStyle( 40 | fontFamily: "OpenSans", 41 | fontSize: 20, 42 | ), 43 | ), 44 | ) 45 | ), 46 | home: MyHomePage(), 47 | ); 48 | } 49 | } 50 | 51 | class MyHomePage extends StatefulWidget { 52 | 53 | @override 54 | _MyHomePageState createState() => _MyHomePageState(); 55 | } 56 | 57 | class _MyHomePageState extends State { 58 | 59 | final List _userTransactions = []; 60 | 61 | List get _recentTransactions{ 62 | return _userTransactions.where((tx) { 63 | return tx.date.isAfter(DateTime.now().subtract(Duration(days: 7))); 64 | }).toList(); 65 | } 66 | 67 | _addNewTransaction(String newTitle, double newAmount, DateTime chosenDate){ 68 | final newTx = Transaction( 69 | id: DateTime.now().toString(), 70 | title: newTitle, 71 | amount: newAmount, 72 | date: chosenDate 73 | ); 74 | setState(() { 75 | _userTransactions.add(newTx); 76 | }); 77 | } 78 | 79 | _startAddNewTransaction(BuildContext ctx){ 80 | showModalBottomSheet(context: ctx, builder: (_) { 81 | return NewTransaction(_addNewTransaction); 82 | }); 83 | } 84 | 85 | _deleteTransaction(String id){ 86 | setState(() { 87 | _userTransactions.removeWhere((element) => element.id == id); 88 | }); 89 | } 90 | 91 | @override 92 | Widget build(BuildContext context) { 93 | 94 | final appBar = AppBar( 95 | title: Text("Personal Expenses",), 96 | actions: [ 97 | IconButton( 98 | icon: Icon(Icons.add), 99 | onPressed: () => _startAddNewTransaction(context), 100 | ) 101 | ], 102 | ); 103 | 104 | return Scaffold( 105 | appBar: appBar, 106 | body: SingleChildScrollView( 107 | child: Column( 108 | crossAxisAlignment: CrossAxisAlignment.center, 109 | children: [ 110 | Container( 111 | height: (MediaQuery.of(context).size.height 112 | - appBar.preferredSize.height 113 | - MediaQuery.of(context).padding.top) * 0.3, 114 | child: Chart(_recentTransactions) 115 | ), 116 | Container( 117 | height: (MediaQuery.of(context).size.height 118 | - appBar.preferredSize.height 119 | - MediaQuery.of(context).padding.top) * 0.7, 120 | child: TransactionList(_userTransactions, _deleteTransaction) 121 | ) 122 | ], 123 | ), 124 | ), 125 | floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, 126 | floatingActionButton: FloatingActionButton( 127 | child: Icon(Icons.add), 128 | onPressed: () => _startAddNewTransaction(context), 129 | ), 130 | ); 131 | } 132 | } 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.0.13" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.6.0" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.4.1" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "2.0.0" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.3" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.14.12" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.4" 60 | cupertino_icons: 61 | dependency: "direct main" 62 | description: 63 | name: cupertino_icons 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.1.3" 67 | flutter: 68 | dependency: "direct main" 69 | description: flutter 70 | source: sdk 71 | version: "0.0.0" 72 | flutter_test: 73 | dependency: "direct dev" 74 | description: flutter 75 | source: sdk 76 | version: "0.0.0" 77 | image: 78 | dependency: transitive 79 | description: 80 | name: image 81 | url: "https://pub.dartlang.org" 82 | source: hosted 83 | version: "2.1.12" 84 | intl: 85 | dependency: "direct main" 86 | description: 87 | name: intl 88 | url: "https://pub.dartlang.org" 89 | source: hosted 90 | version: "0.16.1" 91 | matcher: 92 | dependency: transitive 93 | description: 94 | name: matcher 95 | url: "https://pub.dartlang.org" 96 | source: hosted 97 | version: "0.12.6" 98 | meta: 99 | dependency: transitive 100 | description: 101 | name: meta 102 | url: "https://pub.dartlang.org" 103 | source: hosted 104 | version: "1.1.8" 105 | path: 106 | dependency: transitive 107 | description: 108 | name: path 109 | url: "https://pub.dartlang.org" 110 | source: hosted 111 | version: "1.6.4" 112 | petitparser: 113 | dependency: transitive 114 | description: 115 | name: petitparser 116 | url: "https://pub.dartlang.org" 117 | source: hosted 118 | version: "2.4.0" 119 | quiver: 120 | dependency: transitive 121 | description: 122 | name: quiver 123 | url: "https://pub.dartlang.org" 124 | source: hosted 125 | version: "2.1.3" 126 | sky_engine: 127 | dependency: transitive 128 | description: flutter 129 | source: sdk 130 | version: "0.0.99" 131 | source_span: 132 | dependency: transitive 133 | description: 134 | name: source_span 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.7.0" 138 | stack_trace: 139 | dependency: transitive 140 | description: 141 | name: stack_trace 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "1.9.3" 145 | stream_channel: 146 | dependency: transitive 147 | description: 148 | name: stream_channel 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.0.0" 152 | string_scanner: 153 | dependency: transitive 154 | description: 155 | name: string_scanner 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.0.5" 159 | term_glyph: 160 | dependency: transitive 161 | description: 162 | name: term_glyph 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.1.0" 166 | test_api: 167 | dependency: transitive 168 | description: 169 | name: test_api 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "0.2.15" 173 | typed_data: 174 | dependency: transitive 175 | description: 176 | name: typed_data 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.1.6" 180 | vector_math: 181 | dependency: transitive 182 | description: 183 | name: vector_math 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.0.8" 187 | xml: 188 | dependency: transitive 189 | description: 190 | name: xml 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "3.6.1" 194 | sdks: 195 | dart: ">=2.7.0 <3.0.0" 196 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Playground 2 | Playing around with flutter. Figuring out if it is for babies or not. 3 | 4 | 5 | # This app 6 | **Native Features** 7 | 8 | 9 | 10 | 11 | # Resources: 12 | 1. Travel Information app: 13 | - https://www.youtube.com/watch?v=pTJJsmejUOQ 14 | 2. Flutter and Dart - The Complete Guide: 15 | - https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps 16 | 3. Widget catalog: 17 | - https://flutter.dev/docs/development/ui/widgets 18 | 19 | 20 | 21 | # Continue 22 | 1. https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/learn/lecture/14951040#content 23 | 24 | 25 | 26 | # Third Party libs 27 | 1. Dates 28 | - Intl: https://pub.dev/documentation/intl/latest/ 29 | 2. Provider 30 | - https://pub.dev/packages/provider 31 | 3. HTTP requests 32 | - https://pub.dev/packages/http#-installing-tab- 33 | 4. SharedPreferences 34 | - https://pub.dev/packages/shared_preferences 35 | 4. Image Picker 36 | - https://pub.dev/packages/image_picker 37 | - Capturing an image 38 | 5. path_provider and path packages 39 | - https://pub.dev/packages/path_provider 40 | - Access to android/ios file system to save files 41 | 6. sqflite 42 | - https://pub.dev/packages/sqflite 43 | - https://pub.dev/packages/hive 44 | - Use SQLite on android and ios 45 | 7. Google maps 46 | - https://pub.dev/packages/location 47 | 48 | 49 | 50 | # Questions 51 | 1. Debugging 52 | 2. state 53 | 1. Provider Pattern 54 | 2. Bloc pattern? 55 | 3. architecture? 56 | - block pattern? 57 | 4. Testing? 58 | 5. Restoring list position? (after rotation/background or forward/back navigation) 59 | 6. Dialog behavior on rotation/background 60 | 7. ListView performance 61 | 1. Does is load everything even if not visible? 62 | - ListView.builder() vs ListView(children: []) 63 | 8. Asynchronous work? 64 | 1. async/await and Futures 65 | - This is basically the same as coroutines. Just instead of `suspend` functions you mark a line of code with `await`. Which tells the compile to wait until the `Future` is returned to move to the next line of code. I like this. 66 | 9. Memory leaks? 67 | - Can you leak memory? 68 | - Yes you can. And I have no idea how to detect. 69 | - how can you detect? (ex: Leak Canary on android) 70 | 10. Animations on navigation? 71 | - At this point everything I've seen just looks like an activity navigation. Which looks like crap. 72 | 11. APK / project size? 73 | - How does APK / project size compare with native? 74 | 12. SharedPreferences? 75 | - Shared preferences plugin https://pub.dev/packages/shared_preferences 76 | 13. Caching? 77 | - How does Flutter handle data persistence? (SQLite?...) 78 | 14. Push notifications 79 | - I heard this was difficult 80 | 15. Camera preview manipulation 81 | 1. Capturing an image: https://pub.dev/packages/image_picker#-installing-tab- 82 | 2. It's easy to take simple pictures. But far as I can tell there is no way to build a "custom camera" app. Something where you can apply funny filters, Augmented reality, etc... 83 | 16. Long-running services & WorkManager? 84 | - Suppose something that needs to execute even if the app closes or it's in progress when the app closes 85 | 17. Pagination? 86 | - I'm not sure how to handle pagination with Flutter?... 87 | - TODO: 88 | - Try querying a massive amount of list items (1000+) and displaying them. See if it struggles. 89 | 18. Google maps? 90 | - https://pub.dev/packages/location 91 | 92 | 93 | 94 | # What makes Flutter "Easier" than Native? 95 | 1. Dependency conflicts 96 | - With native, many dependencies do not work with other dependencies. For example, Navigation version 1.2.3 might not work with Fragments version 1.4.2 (not actual versions, this is just an example). This can cause **MASSIVE** headaches when developing. Especially if you are a beginner. 97 | - Flutter has basically one dependency for all Material design widgets. 'package:flutter/material.dart' 98 | 2. Beautiful prebuilt widgets 99 | - There is many prebuilt widgets designed for specific scenarios you run into on mobile. One example that comes to mind is the ListTile. It's awesome for list items as it contains a "leading", "subtitle", "title" and "trailing" param. These params orient the widgets you place inside them into specific positions. On Native you'd need to build a custom adapter and custom layout which is very time consuming. 100 | 3. ... 101 | 102 | 103 | # Things I like 104 | 1. Displaying images from network 105 | - super simple with no third party library needed 106 | - Without a third party on android this is not fun. I can honestly say I don't even know how to do that. 107 | 108 | 109 | # Day 13 (June 26) 110 | 1. Animations 111 | - I don't have a lot of experience with animations on native. But this seems complex. 112 | 2. Using the camera 113 | - use Image picker plugin https://pub.dev/packages/image_picker 114 | 3. Asking for permissions 115 | - This happens automatically it seems? Depending on the plugin you use. It did when I used the camera plugin. 116 | 4. Caching data with SQLite 117 | - sqflite plugin: https://pub.dev/packages/sqflite 118 | - This plugin isn't great. Room is definitely far easier to use. This reminds me of the old SQLiteOpenHelper thing that you used to use for SQLite on Android. 119 | 120 | 121 | 122 | # Day 12 (June 25) 123 | 1. Saving data locally (token for authentication) 124 | 2. Using providers to provide dependencies to other providers 125 | - ex: Providing Auth token from a provider to other providers 126 | - `263. Using the ProxyProvider and Attaching the token...` 127 | - ChangeNotifierProxyProvider 128 | 129 | 130 | 131 | # Day 11 (June 24) 132 | 1. Did all basic CRUD operations today working more with futures. Not particularly impressed or un-impressed. Reminds me of Python. Does the job. 133 | 134 | 135 | # Day 10 (June 23) 136 | 1. Forms and TextFormFields 137 | - Reminds me of HTML forms. Cool how they built a Form widget with Form fields that are built to work together. 138 | 1. This is surprisingly a lot of work. I don't think this is less code than native would be to create a screen for getting inputs from the user. 139 | - `222. Submitting Forms` 140 | - Also dealing with the focus and doing form validation is a lot of work. Definitely this is not more concise than native. 141 | 2. Form validation reminds me of django. You get a boolean that says if the form is valid or not, then take action or show errors. 142 | 2. FocusNode 143 | - Programatically decide where the focus goes after moving from Form fields 144 | - Can leak memory, need to dispose 145 | 3. Futures 146 | - `238. Futures and Async Code` 147 | 4. HTTP requests 148 | - Reminds me of http requests with python. Basically the same. 149 | 5. Async and await 150 | - `241. Working with async and await` 151 | 152 | # Day 9 (June 22) 153 | 1. Dismissible widget 154 | - used to "swipe out" items from a list. Very convenient and easy to use 155 | - Great animation 156 | 2. Started rebuilding my Local DB caching course app using Flutter 157 | - This is to help learn flutter with a project I've already done. (https://github.com/mitchtabian/Local-db-Cache-Retrofit-REST-API-MVVM) 158 | - So far, within about 2 hours I built the complete skeleton with navigation and static data. 159 | 3. Snackbars 160 | - Working with Snackbars was very easy. 161 | 1. Simple to show 162 | 2. Simple to hide if one was already showing and want to show a new one 163 | 3. Simple to incorporate "undo" action 164 | 4. Dialogs 165 | - AlertDialogs are very easy to set up and use the input the user chose. 166 | 167 | # Day 8 (June 18) 168 | 1. Beginning "advanced" state management today. 169 | 2. Provider 170 | - https://pub.dev/packages/provider 171 | - Seems to be the equivalent of LiveData on native? 172 | 3. ChangeNotifier & "**Provider Pattern**" 173 | - ex: `class ProductsProvider with ChangeNotifier` 174 | - Helps to establish "behind the scenes" communication tunnels between widgets 175 | - ex: https://gist.github.com/mitchtabian/a87d9c7ab464c937af25b605f8c2cdb2 176 | 4. ChangeNotifierProvider 177 | - `190. Working with Providers and Listeners` 178 | - For providing a global state provider to widgets lower in the hierarchy 179 | 5. Mixins 180 | - Like a generalized extension 181 | - Can use many mixins but only a single class extension 182 | - ex: `Person extends Mammal with Agility, Consciousness` 183 | - A person is a Mammal. But a person is not "Agility". A person has the ability to use Agility. 184 | 6. `ChangeNotifierProvider.value(value:)` vs `ChangeNotifierProvider(create:)` 185 | - for lists/reusing objects: `ChangeNotifierProvider.value(value:)` 186 | - for new views or stuff that is not reused `ChangeNotifierProvider(create:)` 187 | 7. Consumer with of Provider 188 | - https://gist.github.com/mitchtabian/9b0d00576b24f9eb2ed073de00c67030 189 | - Advantage: 190 | - Only the part of the widget tree that is wrapped with Consumer will be rebuilt. As opposed to using a global Provider which will rebuild the entire tree. 191 | 192 | # Day 7 (June 17) 193 | 1. onUnknownRoute 194 | - Basically this is the web equivalent of a 404 page. 195 | - MaterialApp param 196 | 2. onGenerateRoute 197 | - dynamically generate a route (could be used for dynamically generating screens) 198 | - MaterialApp param 199 | 3. Top Tabs 200 | - `170. Adding TabBar to the AppBar` 201 | - https://gist.github.com/mitchtabian/d16b239d849f8d175d1f6801011dc0ef 202 | - DefaultTabController 203 | - This was very easy to set up and looks good. Much easier than setting this up natively. Very intuitive. 204 | 4. Bottom Tabs 205 | - `171. Adding a bottom TabBar` 206 | - https://gist.github.com/mitchtabian/01c54ffb9362b592641349d7e0d7467b 207 | - Interestingly, setting tabs up on the bottom is much more difficult than tabs on the top. This is not intuitive. 208 | 5. Navigation drawer 209 | - `172. Adding a custom drawer` 210 | - Drawer param in a scaffold 211 | - Pretty simple. But I wouldn't say this is necessarily simpler than on native. 212 | 6. removing items from backstack when navigating 213 | - `Navigator.of(context).pushReplacementNamed(NAV_TABS_SCREEN)` 214 | - This replaces the existing page on the backstack when navigating. This is equally simple on native (with Nav components). 215 | 7. State management 216 | - I have a lot of questions about state management at this point. Because in the course if we want to manage some kind of "global" property we have to pass it around widget constructors which gets very complicated. I believe later in the course I will learn a better system. 217 | 218 | # Day 6 (June 16) 219 | 1. End Expense Tracker app. Beginning to work on Navigation. 220 | - (`https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/learn/lecture/15033798#overview`) 221 | 2. InkWell 222 | - Same as GestureDetector but fires off a ripple effect when tap occurs 223 | 3. Navigator 224 | - `159. Navigating to a New Page` 225 | - `160. Passing Data via the Constructor` 226 | - MaterialPageRoute 227 | - Navigation is much simpler. Especially regarding passing arguments to a new screen. 228 | 1. You can pass constructor arguments to the widgets. On Android you have to use bundles. Much more complex. 229 | - Fragments/Activities can accept constructor arguments, but you must use a Factory (complex). 230 | 2. You can easily access the application stack and push/pull whatever you want with Navigator. 231 | - **downside** 232 | - This is simple, but I could see this getting cumbersom in a large app. Named Routes seem like a better approach. In which case it is not really simpler. It's basically the same as NavigationComponents. 233 | 4. Named Routes 234 | - `161. Named Routes and Passing Data with Named Routes` 235 | - Very similar to website navigation. 236 | - This is a better option for a larger app. Basically you define all the navigation in a "map". 237 | - Advantages: 238 | 1. All routes are defined in main widget so if any application-wide state variables need to be managed it's easy to pass to constructor. 239 | 5. Rounded images 240 | - `165. Displaying Recipe Items & Using Network Images` 241 | - Widget: `ClipRRect` 242 | - Clip the corners of an image 243 | 6. Network images 244 | - `165. Displaying Recipe Items & Using Network Images` 245 | - `Image.network(src)` 246 | - Very easy to display a network image. With Android this is very confusing for beginners because third party libraries are technically the best way. And there is so many. 247 | - No worries about asynchronous loading?... 248 | - No worries about blocking the ui thread?... 249 | 250 | # Day 5 (June 12) 251 | 1. trailing/leading attributes in a ListTile 252 | - Ex: (trailing) Trash can icon at the end of a list item layout. Convenient since this is very common 253 | - Ex: (leading) Something at the front of a list item layout. 254 | 2. Nested Scrolling 255 | - If you have a SingleChildScrollView and a Listview inside it, it works as you would expect. Which is not the case on android. Scrolling is "difficult" to deal with regarding nesting. 256 | - But on flutter it is simple. Whichever widget you touch will scroll. 257 | 3. MediaQuery 258 | - This isn't better than what we have available on android. I prefer the layout designs using xml for this. 259 | 1. holds information: 260 | - Screen pixel ratio 261 | - disable animations 262 | - brightness 263 | - size (width and height of device) 264 | 4. LayoutBuilder 265 | - can wrap a widget in this to apply constraints or get information about the sizing. Similar to ViewTreeObserver on android. 266 | - `119. Using the LayoutBuilder widget` 267 | 5. SystemChrome 268 | - Set allowed device orientations (force portrait only or landscape only) 269 | - system wide settings for application 270 | - `WidgetsFlutterBinding.ensureInitialized();` 271 | - `SystemChrome.setPreferredOrientations( 272 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown] 273 | );` 274 | 6. Build and Flutter Widget Tree 275 | - `137: Widget Tree & Element Tree` 276 | 7. Lifecycle states 277 | - `WidgetsBindingObserver` 278 | - How to listen for the various lifecycle states in a particular widget or app: `146. Understanding the App Lifecycle` 279 | 280 | # Day 4 (June 11) 281 | 1. ListView 282 | - ListView.builder(itemBuilder: <>, itemCount: <>) will **not** load items that are not visible 283 | - This is the `Recyclerview` equivalent 284 | - itemBuilder: is the RecyclerView Adapter basically 285 | - ListView(children[]) will load ALL items, even if they are not visible on screen. 286 | 2. showModalBottomSheet(context: ctx, builder: (bCtx){}) 287 | - This is a nice built-in widget for displaying a bottom sheet. Pretty convenient. 288 | - video: `91. Showing a Model Bottom Sheet` @ 7:55 289 | 3. Navigator 290 | 1. Navigator.of(context).pop(); 291 | - Navigator is a "global" navigation object? Like the backstack on android? 292 | 4. ThemeData(primarySwatch: Colors.purple) 293 | - This is cool. You can easily set the theme to a variety of pre-packaged material colors. 294 | - this isn't that much different than what native does though. You have a theme in stlyes.xml 295 | - *However* this is much less confusing than with android. There is so many different themes and sub-themes. Some don't work with others and cause problems. Flutter seems very straightforward. 296 | - video: `93: configuring and using themes` 297 | 5. Creating a Chart 298 | 1. Creating/drawing shapes is extremely simple compared to native. 299 | - `100. Creating Bars for our Chart` 300 | 6. FittedBox widget 301 | - automatically shrinks text to fit a box 302 | - on android this would be difficult to implement. You'd have to calculate the space and manually set the text size based on testing. With Flutter there is a simple widget that does this. 303 | 7. showDatePicker(context: null, initialDate: null, firstDate: null, lastDate: null) 304 | - nice packaged way to show a date picker 305 | 306 | 307 | # Day 3 (June 4) 308 | 1. Finished ListView + DetailView with static data example 309 | - https://github.com/mitchtabian/FlutterPlayground/tree/listview-static-data 310 | - I'm not amazed by this. I could have built the same thing on android with the same amount of code and time. 311 | - I guess the fact that it is **cross platform** is the real payoff. 312 | 2. Dates 313 | - https://pub.dev/packages/intl#-readme-tab- 314 | - Working with dates is very easy with intl third party library. 315 | 3. Inputs 316 | 1. All inputs must be Strings? 317 | - Obviously I don't like this. b/c you have to do the conversions yourself after the fact. 318 | 4. SingleChildScrollView 319 | - Like a ScrollView? 320 | - This is cool. It would be nice if a Recyclerview was this easy to hook up and delegate scroll behavior to the parent. Often times it has issues if multiple views that can detect gestures are involved. But I wonder... What is the performance like with a massive list? Say 1000 entries with media? 321 | 322 | # Day 2 (June 3) 323 | 1. I like how some color opacity's come prebuilt as constants. 324 | - ex: black12, black26, black87, etc.. 325 | - makes things more consistent across different apps. 326 | - Gives description. Ex: "This is a good contrasting color for light themes." 327 | 2. Images 328 | - It is way easier to display a simple image. No third party library needed. No async knowledge. 329 | 3. Assets 330 | - Getting stuff from assets is much easier. No need for context or any of that BS. Just write the path and boom you got it. 331 | 332 | 333 | # Day 1 (June 2) 334 | 1. Kinda neat. Interesting state management 335 | 336 | 337 | 338 | # Thoughts on Flutter 339 | 1. June 11 340 | - I think Flutter became very popular among "new" developers because: 341 | 1. cross platform 342 | 2. it's easier to hack something together that works. There aren't as many architectural patterns, architectures, etc... And much less judgement from the developer community. Like if you build a piece of shit on native and show the community, they will crucify you. But if you did the same thing with flutter, I doubt anyone would say much. 343 | 2. June 12 344 | - Nothing to say today. 345 | 3. June 16 346 | 1. Navigation 347 | - Navigation is much simpler. Especially regarding passing arguments to a new screen. 348 | - 2 things make it simpler: 349 | 1. You can pass constructor arguments to the widgets. On Android you have to use bundles. Much more complex. 350 | - Fragments/Activities can accept constructor arguments, but you must use a Factory (complex). 351 | 2. You can easily access the application stack and push/pull whatever you want with Navigator. 352 | 4. June 17 353 | 1. I love the way you can build layouts in flutter. 354 | - I wish I could design layouts natively like Flutter does. Hopefully compose allows this. 355 | 2. Setting up tabs was pretty easy. Definitely much more beginner friendly than with native. 356 | 3. Performance wise, it seems like the biggest thing you need to watch out for is prevent widget rebuilds whenever possible. So proper state management is key. 357 | 5. June 18 358 | 1. My first thoughts as I started working this morning were "I really like the way you can build UIs with Flutter". I'm someone who always builds UIs in XML. I never use the design tab. So for me this feels like a 2020 version of that. 359 | 2. Provider is a cool pattern. Basically this is LiveData 360 | 6. June 22: 361 | 1. I started the day by beginning to rebuild another project of mine with Flutter (it is a java app). I struggled to do very basic things. Which is understandable because I have not built something myself yet. I have only watched courses. 362 | - original repo link: https://github.com/mitchtabian/Local-db-Cache-Retrofit-REST-API-MVVM 363 | - Flutter rebuild: https://github.com/mitchtabian/Flutter-Recipes-App 364 | 7. June 23: 365 | 1. Input forms, dealing with focus, and input validation are not simple. This has no advantage over native. 366 | 8. June 26 367 | 1. 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | -------------------------------------------------------------------------------- /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 | 97C146F11CF9000F007C117D /* Supporting Files */, 94 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 95 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 96 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 97 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 98 | ); 99 | path = Runner; 100 | sourceTree = ""; 101 | }; 102 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | ); 106 | name = "Supporting Files"; 107 | sourceTree = ""; 108 | }; 109 | /* End PBXGroup section */ 110 | 111 | /* Begin PBXNativeTarget section */ 112 | 97C146ED1CF9000F007C117D /* Runner */ = { 113 | isa = PBXNativeTarget; 114 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 115 | buildPhases = ( 116 | 9740EEB61CF901F6004384FC /* Run Script */, 117 | 97C146EA1CF9000F007C117D /* Sources */, 118 | 97C146EB1CF9000F007C117D /* Frameworks */, 119 | 97C146EC1CF9000F007C117D /* Resources */, 120 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 121 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = Runner; 128 | productName = Runner; 129 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | 97C146E61CF9000F007C117D /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastUpgradeCheck = 1020; 139 | ORGANIZATIONNAME = ""; 140 | TargetAttributes = { 141 | 97C146ED1CF9000F007C117D = { 142 | CreatedOnToolsVersion = 7.3.1; 143 | LastSwiftMigration = 1100; 144 | }; 145 | }; 146 | }; 147 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 148 | compatibilityVersion = "Xcode 9.3"; 149 | developmentRegion = en; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | Base, 154 | ); 155 | mainGroup = 97C146E51CF9000F007C117D; 156 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 157 | projectDirPath = ""; 158 | projectRoot = ""; 159 | targets = ( 160 | 97C146ED1CF9000F007C117D /* Runner */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXResourcesBuildPhase section */ 166 | 97C146EC1CF9000F007C117D /* Resources */ = { 167 | isa = PBXResourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 171 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 172 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 173 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXResourcesBuildPhase section */ 178 | 179 | /* Begin PBXShellScriptBuildPhase section */ 180 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 181 | isa = PBXShellScriptBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | ); 185 | inputPaths = ( 186 | ); 187 | name = "Thin Binary"; 188 | outputPaths = ( 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | shellPath = /bin/sh; 192 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 193 | }; 194 | 9740EEB61CF901F6004384FC /* Run Script */ = { 195 | isa = PBXShellScriptBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | ); 199 | inputPaths = ( 200 | ); 201 | name = "Run Script"; 202 | outputPaths = ( 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | shellPath = /bin/sh; 206 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 207 | }; 208 | /* End PBXShellScriptBuildPhase section */ 209 | 210 | /* Begin PBXSourcesBuildPhase section */ 211 | 97C146EA1CF9000F007C117D /* Sources */ = { 212 | isa = PBXSourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 216 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXSourcesBuildPhase section */ 221 | 222 | /* Begin PBXVariantGroup section */ 223 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C146FB1CF9000F007C117D /* Base */, 227 | ); 228 | name = Main.storyboard; 229 | sourceTree = ""; 230 | }; 231 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 232 | isa = PBXVariantGroup; 233 | children = ( 234 | 97C147001CF9000F007C117D /* Base */, 235 | ); 236 | name = LaunchScreen.storyboard; 237 | sourceTree = ""; 238 | }; 239 | /* End PBXVariantGroup section */ 240 | 241 | /* Begin XCBuildConfiguration section */ 242 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 243 | isa = XCBuildConfiguration; 244 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 245 | buildSettings = { 246 | ALWAYS_SEARCH_USER_PATHS = NO; 247 | CLANG_ANALYZER_NONNULL = YES; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_ENABLE_MODULES = YES; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 253 | CLANG_WARN_BOOL_CONVERSION = YES; 254 | CLANG_WARN_COMMA = YES; 255 | CLANG_WARN_CONSTANT_CONVERSION = YES; 256 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INFINITE_RECURSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 263 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 264 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 266 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 267 | CLANG_WARN_STRICT_PROTOTYPES = YES; 268 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 269 | CLANG_WARN_UNREACHABLE_CODE = YES; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 272 | COPY_PHASE_STRIP = NO; 273 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 274 | ENABLE_NS_ASSERTIONS = NO; 275 | ENABLE_STRICT_OBJC_MSGSEND = YES; 276 | GCC_C_LANGUAGE_STANDARD = gnu99; 277 | GCC_NO_COMMON_BLOCKS = YES; 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 285 | MTL_ENABLE_DEBUG_INFO = NO; 286 | SDKROOT = iphoneos; 287 | SUPPORTED_PLATFORMS = iphoneos; 288 | TARGETED_DEVICE_FAMILY = "1,2"; 289 | VALIDATE_PRODUCT = YES; 290 | }; 291 | name = Profile; 292 | }; 293 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 294 | isa = XCBuildConfiguration; 295 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 296 | buildSettings = { 297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 298 | CLANG_ENABLE_MODULES = YES; 299 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 300 | ENABLE_BITCODE = NO; 301 | FRAMEWORK_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "$(PROJECT_DIR)/Flutter", 304 | ); 305 | INFOPLIST_FILE = Runner/Info.plist; 306 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 307 | LIBRARY_SEARCH_PATHS = ( 308 | "$(inherited)", 309 | "$(PROJECT_DIR)/Flutter", 310 | ); 311 | PRODUCT_BUNDLE_IDENTIFIER = com.codingwithmitch.firstflutterapp; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 314 | SWIFT_VERSION = 5.0; 315 | VERSIONING_SYSTEM = "apple-generic"; 316 | }; 317 | name = Profile; 318 | }; 319 | 97C147031CF9000F007C117D /* Debug */ = { 320 | isa = XCBuildConfiguration; 321 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 322 | buildSettings = { 323 | ALWAYS_SEARCH_USER_PATHS = NO; 324 | CLANG_ANALYZER_NONNULL = YES; 325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 326 | CLANG_CXX_LIBRARY = "libc++"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 330 | CLANG_WARN_BOOL_CONVERSION = YES; 331 | CLANG_WARN_COMMA = YES; 332 | CLANG_WARN_CONSTANT_CONVERSION = YES; 333 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_EMPTY_BODY = YES; 336 | CLANG_WARN_ENUM_CONVERSION = YES; 337 | CLANG_WARN_INFINITE_RECURSION = YES; 338 | CLANG_WARN_INT_CONVERSION = YES; 339 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 340 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 341 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 344 | CLANG_WARN_STRICT_PROTOTYPES = YES; 345 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 346 | CLANG_WARN_UNREACHABLE_CODE = YES; 347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 349 | COPY_PHASE_STRIP = NO; 350 | DEBUG_INFORMATION_FORMAT = dwarf; 351 | ENABLE_STRICT_OBJC_MSGSEND = YES; 352 | ENABLE_TESTABILITY = YES; 353 | GCC_C_LANGUAGE_STANDARD = gnu99; 354 | GCC_DYNAMIC_NO_PIC = NO; 355 | GCC_NO_COMMON_BLOCKS = YES; 356 | GCC_OPTIMIZATION_LEVEL = 0; 357 | GCC_PREPROCESSOR_DEFINITIONS = ( 358 | "DEBUG=1", 359 | "$(inherited)", 360 | ); 361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 362 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 363 | GCC_WARN_UNDECLARED_SELECTOR = YES; 364 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 365 | GCC_WARN_UNUSED_FUNCTION = YES; 366 | GCC_WARN_UNUSED_VARIABLE = YES; 367 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 368 | MTL_ENABLE_DEBUG_INFO = YES; 369 | ONLY_ACTIVE_ARCH = YES; 370 | SDKROOT = iphoneos; 371 | TARGETED_DEVICE_FAMILY = "1,2"; 372 | }; 373 | name = Debug; 374 | }; 375 | 97C147041CF9000F007C117D /* Release */ = { 376 | isa = XCBuildConfiguration; 377 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 378 | buildSettings = { 379 | ALWAYS_SEARCH_USER_PATHS = NO; 380 | CLANG_ANALYZER_NONNULL = YES; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INFINITE_RECURSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 400 | CLANG_WARN_STRICT_PROTOTYPES = YES; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 407 | ENABLE_NS_ASSERTIONS = NO; 408 | ENABLE_STRICT_OBJC_MSGSEND = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_NO_COMMON_BLOCKS = YES; 411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 413 | GCC_WARN_UNDECLARED_SELECTOR = YES; 414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 415 | GCC_WARN_UNUSED_FUNCTION = YES; 416 | GCC_WARN_UNUSED_VARIABLE = YES; 417 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 418 | MTL_ENABLE_DEBUG_INFO = NO; 419 | SDKROOT = iphoneos; 420 | SUPPORTED_PLATFORMS = iphoneos; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 422 | TARGETED_DEVICE_FAMILY = "1,2"; 423 | VALIDATE_PRODUCT = YES; 424 | }; 425 | name = Release; 426 | }; 427 | 97C147061CF9000F007C117D /* Debug */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | FRAMEWORK_SEARCH_PATHS = ( 436 | "$(inherited)", 437 | "$(PROJECT_DIR)/Flutter", 438 | ); 439 | INFOPLIST_FILE = Runner/Info.plist; 440 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 441 | LIBRARY_SEARCH_PATHS = ( 442 | "$(inherited)", 443 | "$(PROJECT_DIR)/Flutter", 444 | ); 445 | PRODUCT_BUNDLE_IDENTIFIER = com.codingwithmitch.firstflutterapp; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 448 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 449 | SWIFT_VERSION = 5.0; 450 | VERSIONING_SYSTEM = "apple-generic"; 451 | }; 452 | name = Debug; 453 | }; 454 | 97C147071CF9000F007C117D /* Release */ = { 455 | isa = XCBuildConfiguration; 456 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 457 | buildSettings = { 458 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 459 | CLANG_ENABLE_MODULES = YES; 460 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 461 | ENABLE_BITCODE = NO; 462 | FRAMEWORK_SEARCH_PATHS = ( 463 | "$(inherited)", 464 | "$(PROJECT_DIR)/Flutter", 465 | ); 466 | INFOPLIST_FILE = Runner/Info.plist; 467 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 468 | LIBRARY_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "$(PROJECT_DIR)/Flutter", 471 | ); 472 | PRODUCT_BUNDLE_IDENTIFIER = com.codingwithmitch.firstflutterapp; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 475 | SWIFT_VERSION = 5.0; 476 | VERSIONING_SYSTEM = "apple-generic"; 477 | }; 478 | name = Release; 479 | }; 480 | /* End XCBuildConfiguration section */ 481 | 482 | /* Begin XCConfigurationList section */ 483 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 484 | isa = XCConfigurationList; 485 | buildConfigurations = ( 486 | 97C147031CF9000F007C117D /* Debug */, 487 | 97C147041CF9000F007C117D /* Release */, 488 | 249021D3217E4FDB00AE95B9 /* Profile */, 489 | ); 490 | defaultConfigurationIsVisible = 0; 491 | defaultConfigurationName = Release; 492 | }; 493 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 97C147061CF9000F007C117D /* Debug */, 497 | 97C147071CF9000F007C117D /* Release */, 498 | 249021D4217E4FDB00AE95B9 /* Profile */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | /* End XCConfigurationList section */ 504 | }; 505 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 506 | } 507 | --------------------------------------------------------------------------------