├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutter_tips_and_examples │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── audios │ └── example_audio.mp3 ├── images │ └── junior_logo_white.png └── message_bubble.json ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h └── RunnerTests │ └── RunnerTests.swift ├── lib ├── 01_debounce_and_form_validation.dart ├── 02_interactive_drawing_canvas.dart ├── 03_bar_charts.dart ├── 04_copy_and_paste.dart ├── 05_lottie_animations_with_color_filter.dart ├── 06_carousel_slider.dart ├── 07_avatar_stack_animation.dart ├── 08_text_and_image_animation.dart ├── 09_speech_to_text_with_whisper.dart ├── 10_popover.dart ├── 11_app_bar_banner_with_animation.dart ├── 12_enhanced_enums.dart ├── 13_2d_scrolling.dart ├── 14_ultra_gradients.dart ├── 15_digital_signature.dart ├── 16_sparkline_chart.dart ├── 17_funnel_chart.dart ├── 18_radial_bar_chart.dart └── 19_analytics_view.dart ├── pubspec.lock ├── pubspec.yaml └── web ├── favicon.png ├── icons ├── Icon-192.png ├── Icon-512.png ├── Icon-maskable-192.png └── Icon-maskable-512.png ├── index.html └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 17 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 18 | - platform: android 19 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 20 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 21 | - platform: ios 22 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 23 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 24 | - platform: linux 25 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 26 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 27 | - platform: macos 28 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 29 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 30 | - platform: web 31 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 32 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 33 | - platform: windows 34 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 35 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_tips_and_examples 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /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 | namespace "com.example.flutter_tips_and_examples" 30 | compileSdkVersion flutter.compileSdkVersion 31 | ndkVersion flutter.ndkVersion 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | kotlinOptions { 39 | jvmTarget = '1.8' 40 | } 41 | 42 | sourceSets { 43 | main.java.srcDirs += 'src/main/kotlin' 44 | } 45 | 46 | defaultConfig { 47 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 48 | applicationId "com.example.flutter_tips_and_examples" 49 | // You can update the following values to match your application needs. 50 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 51 | minSdkVersion flutter.minSdkVersion 52 | targetSdkVersion flutter.targetSdkVersion 53 | versionCode flutterVersionCode.toInteger() 54 | versionName flutterVersionName 55 | } 56 | 57 | buildTypes { 58 | release { 59 | // TODO: Add your own signing config for the release build. 60 | // Signing with the debug keys for now, so `flutter run --release` works. 61 | signingConfig signingConfigs.debug 62 | } 63 | } 64 | } 65 | 66 | flutter { 67 | source '../..' 68 | } 69 | 70 | dependencies { 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 72 | } 73 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_tips_and_examples/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_tips_and_examples 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.3.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 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 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/audios/example_audio.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/assets/audios/example_audio.mp3 -------------------------------------------------------------------------------- /assets/images/junior_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/assets/images/junior_logo_white.png -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - url_launcher_ios (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | url_launcher_ios: 14 | :path: ".symlinks/plugins/url_launcher_ios/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 18 | url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 19 | 20 | PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189 21 | 22 | COCOAPODS: 1.12.1 23 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 05552187CE009DF942D52F52 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98DFBA283516A0DF4C8CA392 /* Pods_RunnerTests.framework */; }; 11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 12 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 13 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | C6C6882AD46991A271088719 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAA1C4556AA462A7093F64A3 /* Pods_Runner.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 27 | remoteInfo = Runner; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 10; 37 | files = ( 38 | ); 39 | name = "Embed Frameworks"; 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 02B48357D122DDF3565B31D6 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 46 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 47 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 48 | 256304636474A56E7C0554BE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 49 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 50 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 52 | 3BA68C61D1E20BB5FF7835E5 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 53 | 4BF52782E85210B2DB7A225B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 54 | 58BF242BE9F16D33CAB2C6F1 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 55 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 56 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 57 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 58 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 59 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 60 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 62 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 63 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 64 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | 98DFBA283516A0DF4C8CA392 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | AAA1C4556AA462A7093F64A3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | D0AA6012D0F5DD4C003F65E2 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 2DA6FFF5A1A343A18EA757A6 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | 05552187CE009DF942D52F52 /* Pods_RunnerTests.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | C6C6882AD46991A271088719 /* Pods_Runner.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 94 | ); 95 | path = RunnerTests; 96 | sourceTree = ""; 97 | }; 98 | 34C485C8DBA34EA359ED47CF /* Pods */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 256304636474A56E7C0554BE /* Pods-Runner.debug.xcconfig */, 102 | D0AA6012D0F5DD4C003F65E2 /* Pods-Runner.release.xcconfig */, 103 | 3BA68C61D1E20BB5FF7835E5 /* Pods-Runner.profile.xcconfig */, 104 | 4BF52782E85210B2DB7A225B /* Pods-RunnerTests.debug.xcconfig */, 105 | 58BF242BE9F16D33CAB2C6F1 /* Pods-RunnerTests.release.xcconfig */, 106 | 02B48357D122DDF3565B31D6 /* Pods-RunnerTests.profile.xcconfig */, 107 | ); 108 | name = Pods; 109 | path = Pods; 110 | sourceTree = ""; 111 | }; 112 | 52D105E22E6D776B8D3CDE38 /* Frameworks */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | AAA1C4556AA462A7093F64A3 /* Pods_Runner.framework */, 116 | 98DFBA283516A0DF4C8CA392 /* Pods_RunnerTests.framework */, 117 | ); 118 | name = Frameworks; 119 | sourceTree = ""; 120 | }; 121 | 9740EEB11CF90186004384FC /* Flutter */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 125 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 126 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 127 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 128 | ); 129 | name = Flutter; 130 | sourceTree = ""; 131 | }; 132 | 97C146E51CF9000F007C117D = { 133 | isa = PBXGroup; 134 | children = ( 135 | 9740EEB11CF90186004384FC /* Flutter */, 136 | 97C146F01CF9000F007C117D /* Runner */, 137 | 97C146EF1CF9000F007C117D /* Products */, 138 | 331C8082294A63A400263BE5 /* RunnerTests */, 139 | 34C485C8DBA34EA359ED47CF /* Pods */, 140 | 52D105E22E6D776B8D3CDE38 /* Frameworks */, 141 | ); 142 | sourceTree = ""; 143 | }; 144 | 97C146EF1CF9000F007C117D /* Products */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 97C146EE1CF9000F007C117D /* Runner.app */, 148 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 149 | ); 150 | name = Products; 151 | sourceTree = ""; 152 | }; 153 | 97C146F01CF9000F007C117D /* Runner */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 157 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 158 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 159 | 97C147021CF9000F007C117D /* Info.plist */, 160 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 161 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 162 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 163 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 164 | ); 165 | path = Runner; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 174 | buildPhases = ( 175 | 8A20DB9F5340E9B8E1528D9F /* [CP] Check Pods Manifest.lock */, 176 | 331C807D294A63A400263BE5 /* Sources */, 177 | 331C807F294A63A400263BE5 /* Resources */, 178 | 2DA6FFF5A1A343A18EA757A6 /* Frameworks */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 184 | ); 185 | name = RunnerTests; 186 | productName = RunnerTests; 187 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 188 | productType = "com.apple.product-type.bundle.unit-test"; 189 | }; 190 | 97C146ED1CF9000F007C117D /* Runner */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 193 | buildPhases = ( 194 | DEBC87665BD41A2AD7E6BE04 /* [CP] Check Pods Manifest.lock */, 195 | 9740EEB61CF901F6004384FC /* Run Script */, 196 | 97C146EA1CF9000F007C117D /* Sources */, 197 | 97C146EB1CF9000F007C117D /* Frameworks */, 198 | 97C146EC1CF9000F007C117D /* Resources */, 199 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 200 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 201 | 0F1E8E38DC8793ABC542BD6B /* [CP] Embed Pods Frameworks */, 202 | ); 203 | buildRules = ( 204 | ); 205 | dependencies = ( 206 | ); 207 | name = Runner; 208 | productName = Runner; 209 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 210 | productType = "com.apple.product-type.application"; 211 | }; 212 | /* End PBXNativeTarget section */ 213 | 214 | /* Begin PBXProject section */ 215 | 97C146E61CF9000F007C117D /* Project object */ = { 216 | isa = PBXProject; 217 | attributes = { 218 | LastUpgradeCheck = 1430; 219 | ORGANIZATIONNAME = ""; 220 | TargetAttributes = { 221 | 331C8080294A63A400263BE5 = { 222 | CreatedOnToolsVersion = 14.0; 223 | TestTargetID = 97C146ED1CF9000F007C117D; 224 | }; 225 | 97C146ED1CF9000F007C117D = { 226 | CreatedOnToolsVersion = 7.3.1; 227 | LastSwiftMigration = 1100; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 232 | compatibilityVersion = "Xcode 9.3"; 233 | developmentRegion = en; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | ); 239 | mainGroup = 97C146E51CF9000F007C117D; 240 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 241 | projectDirPath = ""; 242 | projectRoot = ""; 243 | targets = ( 244 | 97C146ED1CF9000F007C117D /* Runner */, 245 | 331C8080294A63A400263BE5 /* RunnerTests */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 331C807F294A63A400263BE5 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | 97C146EC1CF9000F007C117D /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 263 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 264 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 265 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | /* End PBXResourcesBuildPhase section */ 270 | 271 | /* Begin PBXShellScriptBuildPhase section */ 272 | 0F1E8E38DC8793ABC542BD6B /* [CP] Embed Pods Frameworks */ = { 273 | isa = PBXShellScriptBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | inputFileListPaths = ( 278 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 279 | ); 280 | name = "[CP] Embed Pods Frameworks"; 281 | outputFileListPaths = ( 282 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | shellPath = /bin/sh; 286 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 287 | showEnvVarsInLog = 0; 288 | }; 289 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | alwaysOutOfDate = 1; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | ); 295 | inputPaths = ( 296 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 297 | ); 298 | name = "Thin Binary"; 299 | outputPaths = ( 300 | ); 301 | runOnlyForDeploymentPostprocessing = 0; 302 | shellPath = /bin/sh; 303 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 304 | }; 305 | 8A20DB9F5340E9B8E1528D9F /* [CP] Check Pods Manifest.lock */ = { 306 | isa = PBXShellScriptBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | ); 310 | inputFileListPaths = ( 311 | ); 312 | inputPaths = ( 313 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 314 | "${PODS_ROOT}/Manifest.lock", 315 | ); 316 | name = "[CP] Check Pods Manifest.lock"; 317 | outputFileListPaths = ( 318 | ); 319 | outputPaths = ( 320 | "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | shellPath = /bin/sh; 324 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 325 | showEnvVarsInLog = 0; 326 | }; 327 | 9740EEB61CF901F6004384FC /* Run Script */ = { 328 | isa = PBXShellScriptBuildPhase; 329 | alwaysOutOfDate = 1; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | inputPaths = ( 334 | ); 335 | name = "Run Script"; 336 | outputPaths = ( 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | shellPath = /bin/sh; 340 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 341 | }; 342 | DEBC87665BD41A2AD7E6BE04 /* [CP] Check Pods Manifest.lock */ = { 343 | isa = PBXShellScriptBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | ); 347 | inputFileListPaths = ( 348 | ); 349 | inputPaths = ( 350 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 351 | "${PODS_ROOT}/Manifest.lock", 352 | ); 353 | name = "[CP] Check Pods Manifest.lock"; 354 | outputFileListPaths = ( 355 | ); 356 | outputPaths = ( 357 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | shellPath = /bin/sh; 361 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 362 | showEnvVarsInLog = 0; 363 | }; 364 | /* End PBXShellScriptBuildPhase section */ 365 | 366 | /* Begin PBXSourcesBuildPhase section */ 367 | 331C807D294A63A400263BE5 /* Sources */ = { 368 | isa = PBXSourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | 97C146EA1CF9000F007C117D /* Sources */ = { 376 | isa = PBXSourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 380 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | /* End PBXSourcesBuildPhase section */ 385 | 386 | /* Begin PBXTargetDependency section */ 387 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 388 | isa = PBXTargetDependency; 389 | target = 97C146ED1CF9000F007C117D /* Runner */; 390 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 391 | }; 392 | /* End PBXTargetDependency section */ 393 | 394 | /* Begin PBXVariantGroup section */ 395 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 396 | isa = PBXVariantGroup; 397 | children = ( 398 | 97C146FB1CF9000F007C117D /* Base */, 399 | ); 400 | name = Main.storyboard; 401 | sourceTree = ""; 402 | }; 403 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 404 | isa = PBXVariantGroup; 405 | children = ( 406 | 97C147001CF9000F007C117D /* Base */, 407 | ); 408 | name = LaunchScreen.storyboard; 409 | sourceTree = ""; 410 | }; 411 | /* End PBXVariantGroup section */ 412 | 413 | /* Begin XCBuildConfiguration section */ 414 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | CLANG_ANALYZER_NONNULL = YES; 419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 420 | CLANG_CXX_LIBRARY = "libc++"; 421 | CLANG_ENABLE_MODULES = YES; 422 | CLANG_ENABLE_OBJC_ARC = YES; 423 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 424 | CLANG_WARN_BOOL_CONVERSION = YES; 425 | CLANG_WARN_COMMA = YES; 426 | CLANG_WARN_CONSTANT_CONVERSION = YES; 427 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INFINITE_RECURSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 435 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 438 | CLANG_WARN_STRICT_PROTOTYPES = YES; 439 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 440 | CLANG_WARN_UNREACHABLE_CODE = YES; 441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 443 | COPY_PHASE_STRIP = NO; 444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 445 | ENABLE_NS_ASSERTIONS = NO; 446 | ENABLE_STRICT_OBJC_MSGSEND = YES; 447 | GCC_C_LANGUAGE_STANDARD = gnu99; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 450 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 451 | GCC_WARN_UNDECLARED_SELECTOR = YES; 452 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 453 | GCC_WARN_UNUSED_FUNCTION = YES; 454 | GCC_WARN_UNUSED_VARIABLE = YES; 455 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 456 | MTL_ENABLE_DEBUG_INFO = NO; 457 | SDKROOT = iphoneos; 458 | SUPPORTED_PLATFORMS = iphoneos; 459 | TARGETED_DEVICE_FAMILY = "1,2"; 460 | VALIDATE_PRODUCT = YES; 461 | }; 462 | name = Profile; 463 | }; 464 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 467 | buildSettings = { 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | CLANG_ENABLE_MODULES = YES; 470 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 471 | DEVELOPMENT_TEAM = FRCN5G7TWX; 472 | ENABLE_BITCODE = NO; 473 | INFOPLIST_FILE = Runner/Info.plist; 474 | LD_RUNPATH_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "@executable_path/Frameworks", 477 | ); 478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 481 | SWIFT_VERSION = 5.0; 482 | VERSIONING_SYSTEM = "apple-generic"; 483 | }; 484 | name = Profile; 485 | }; 486 | 331C8088294A63A400263BE5 /* Debug */ = { 487 | isa = XCBuildConfiguration; 488 | baseConfigurationReference = 4BF52782E85210B2DB7A225B /* Pods-RunnerTests.debug.xcconfig */; 489 | buildSettings = { 490 | BUNDLE_LOADER = "$(TEST_HOST)"; 491 | CODE_SIGN_STYLE = Automatic; 492 | CURRENT_PROJECT_VERSION = 1; 493 | GENERATE_INFOPLIST_FILE = YES; 494 | MARKETING_VERSION = 1.0; 495 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples.RunnerTests; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 498 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 499 | SWIFT_VERSION = 5.0; 500 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 501 | }; 502 | name = Debug; 503 | }; 504 | 331C8089294A63A400263BE5 /* Release */ = { 505 | isa = XCBuildConfiguration; 506 | baseConfigurationReference = 58BF242BE9F16D33CAB2C6F1 /* Pods-RunnerTests.release.xcconfig */; 507 | buildSettings = { 508 | BUNDLE_LOADER = "$(TEST_HOST)"; 509 | CODE_SIGN_STYLE = Automatic; 510 | CURRENT_PROJECT_VERSION = 1; 511 | GENERATE_INFOPLIST_FILE = YES; 512 | MARKETING_VERSION = 1.0; 513 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples.RunnerTests; 514 | PRODUCT_NAME = "$(TARGET_NAME)"; 515 | SWIFT_VERSION = 5.0; 516 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 517 | }; 518 | name = Release; 519 | }; 520 | 331C808A294A63A400263BE5 /* Profile */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = 02B48357D122DDF3565B31D6 /* Pods-RunnerTests.profile.xcconfig */; 523 | buildSettings = { 524 | BUNDLE_LOADER = "$(TEST_HOST)"; 525 | CODE_SIGN_STYLE = Automatic; 526 | CURRENT_PROJECT_VERSION = 1; 527 | GENERATE_INFOPLIST_FILE = YES; 528 | MARKETING_VERSION = 1.0; 529 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples.RunnerTests; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | SWIFT_VERSION = 5.0; 532 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 533 | }; 534 | name = Profile; 535 | }; 536 | 97C147031CF9000F007C117D /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | ALWAYS_SEARCH_USER_PATHS = NO; 540 | CLANG_ANALYZER_NONNULL = YES; 541 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 542 | CLANG_CXX_LIBRARY = "libc++"; 543 | CLANG_ENABLE_MODULES = YES; 544 | CLANG_ENABLE_OBJC_ARC = YES; 545 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 546 | CLANG_WARN_BOOL_CONVERSION = YES; 547 | CLANG_WARN_COMMA = YES; 548 | CLANG_WARN_CONSTANT_CONVERSION = YES; 549 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 551 | CLANG_WARN_EMPTY_BODY = YES; 552 | CLANG_WARN_ENUM_CONVERSION = YES; 553 | CLANG_WARN_INFINITE_RECURSION = YES; 554 | CLANG_WARN_INT_CONVERSION = YES; 555 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 556 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 558 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 560 | CLANG_WARN_STRICT_PROTOTYPES = YES; 561 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 562 | CLANG_WARN_UNREACHABLE_CODE = YES; 563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 564 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 565 | COPY_PHASE_STRIP = NO; 566 | DEBUG_INFORMATION_FORMAT = dwarf; 567 | ENABLE_STRICT_OBJC_MSGSEND = YES; 568 | ENABLE_TESTABILITY = YES; 569 | GCC_C_LANGUAGE_STANDARD = gnu99; 570 | GCC_DYNAMIC_NO_PIC = NO; 571 | GCC_NO_COMMON_BLOCKS = YES; 572 | GCC_OPTIMIZATION_LEVEL = 0; 573 | GCC_PREPROCESSOR_DEFINITIONS = ( 574 | "DEBUG=1", 575 | "$(inherited)", 576 | ); 577 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 578 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 579 | GCC_WARN_UNDECLARED_SELECTOR = YES; 580 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 581 | GCC_WARN_UNUSED_FUNCTION = YES; 582 | GCC_WARN_UNUSED_VARIABLE = YES; 583 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 584 | MTL_ENABLE_DEBUG_INFO = YES; 585 | ONLY_ACTIVE_ARCH = YES; 586 | SDKROOT = iphoneos; 587 | TARGETED_DEVICE_FAMILY = "1,2"; 588 | }; 589 | name = Debug; 590 | }; 591 | 97C147041CF9000F007C117D /* Release */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | ALWAYS_SEARCH_USER_PATHS = NO; 595 | CLANG_ANALYZER_NONNULL = YES; 596 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 597 | CLANG_CXX_LIBRARY = "libc++"; 598 | CLANG_ENABLE_MODULES = YES; 599 | CLANG_ENABLE_OBJC_ARC = YES; 600 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 601 | CLANG_WARN_BOOL_CONVERSION = YES; 602 | CLANG_WARN_COMMA = YES; 603 | CLANG_WARN_CONSTANT_CONVERSION = YES; 604 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 605 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 606 | CLANG_WARN_EMPTY_BODY = YES; 607 | CLANG_WARN_ENUM_CONVERSION = YES; 608 | CLANG_WARN_INFINITE_RECURSION = YES; 609 | CLANG_WARN_INT_CONVERSION = YES; 610 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 611 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 612 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 613 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 614 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 615 | CLANG_WARN_STRICT_PROTOTYPES = YES; 616 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 617 | CLANG_WARN_UNREACHABLE_CODE = YES; 618 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 619 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 620 | COPY_PHASE_STRIP = NO; 621 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 622 | ENABLE_NS_ASSERTIONS = NO; 623 | ENABLE_STRICT_OBJC_MSGSEND = YES; 624 | GCC_C_LANGUAGE_STANDARD = gnu99; 625 | GCC_NO_COMMON_BLOCKS = YES; 626 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 627 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 628 | GCC_WARN_UNDECLARED_SELECTOR = YES; 629 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 630 | GCC_WARN_UNUSED_FUNCTION = YES; 631 | GCC_WARN_UNUSED_VARIABLE = YES; 632 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 633 | MTL_ENABLE_DEBUG_INFO = NO; 634 | SDKROOT = iphoneos; 635 | SUPPORTED_PLATFORMS = iphoneos; 636 | SWIFT_COMPILATION_MODE = wholemodule; 637 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 638 | TARGETED_DEVICE_FAMILY = "1,2"; 639 | VALIDATE_PRODUCT = YES; 640 | }; 641 | name = Release; 642 | }; 643 | 97C147061CF9000F007C117D /* Debug */ = { 644 | isa = XCBuildConfiguration; 645 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 646 | buildSettings = { 647 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 648 | CLANG_ENABLE_MODULES = YES; 649 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 650 | DEVELOPMENT_TEAM = FRCN5G7TWX; 651 | ENABLE_BITCODE = NO; 652 | INFOPLIST_FILE = Runner/Info.plist; 653 | LD_RUNPATH_SEARCH_PATHS = ( 654 | "$(inherited)", 655 | "@executable_path/Frameworks", 656 | ); 657 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples; 658 | PRODUCT_NAME = "$(TARGET_NAME)"; 659 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 660 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 661 | SWIFT_VERSION = 5.0; 662 | VERSIONING_SYSTEM = "apple-generic"; 663 | }; 664 | name = Debug; 665 | }; 666 | 97C147071CF9000F007C117D /* Release */ = { 667 | isa = XCBuildConfiguration; 668 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 669 | buildSettings = { 670 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 671 | CLANG_ENABLE_MODULES = YES; 672 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 673 | DEVELOPMENT_TEAM = FRCN5G7TWX; 674 | ENABLE_BITCODE = NO; 675 | INFOPLIST_FILE = Runner/Info.plist; 676 | LD_RUNPATH_SEARCH_PATHS = ( 677 | "$(inherited)", 678 | "@executable_path/Frameworks", 679 | ); 680 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterTipsAndExamples; 681 | PRODUCT_NAME = "$(TARGET_NAME)"; 682 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 683 | SWIFT_VERSION = 5.0; 684 | VERSIONING_SYSTEM = "apple-generic"; 685 | }; 686 | name = Release; 687 | }; 688 | /* End XCBuildConfiguration section */ 689 | 690 | /* Begin XCConfigurationList section */ 691 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 331C8088294A63A400263BE5 /* Debug */, 695 | 331C8089294A63A400263BE5 /* Release */, 696 | 331C808A294A63A400263BE5 /* Profile */, 697 | ); 698 | defaultConfigurationIsVisible = 0; 699 | defaultConfigurationName = Release; 700 | }; 701 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 702 | isa = XCConfigurationList; 703 | buildConfigurations = ( 704 | 97C147031CF9000F007C117D /* Debug */, 705 | 97C147041CF9000F007C117D /* Release */, 706 | 249021D3217E4FDB00AE95B9 /* Profile */, 707 | ); 708 | defaultConfigurationIsVisible = 0; 709 | defaultConfigurationName = Release; 710 | }; 711 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 712 | isa = XCConfigurationList; 713 | buildConfigurations = ( 714 | 97C147061CF9000F007C117D /* Debug */, 715 | 97C147071CF9000F007C117D /* Release */, 716 | 249021D4217E4FDB00AE95B9 /* Profile */, 717 | ); 718 | defaultConfigurationIsVisible = 0; 719 | defaultConfigurationName = Release; 720 | }; 721 | /* End XCConfigurationList section */ 722 | }; 723 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 724 | } 725 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/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/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter Tips And Examples 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_tips_and_examples 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/01_debounce_and_form_validation.dart: -------------------------------------------------------------------------------- 1 | // Debounce and Form Validation by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'dart:async'; 5 | 6 | import 'package:flutter/material.dart'; 7 | 8 | void main() { 9 | runApp(const MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | theme: ThemeData.light(useMaterial3: true), 19 | home: const SignInWithValidationAndDebounce(), 20 | ); 21 | } 22 | } 23 | 24 | class SignInWithValidationAndDebounce extends StatefulWidget { 25 | const SignInWithValidationAndDebounce({Key? key}) : super(key: key); 26 | 27 | @override 28 | State createState() => 29 | _SignInWithValidationAndDebounceState(); 30 | } 31 | 32 | class _SignInWithValidationAndDebounceState 33 | extends State { 34 | Timer? debounce; 35 | 36 | final _emailController = TextEditingController(); 37 | final _passwordController = TextEditingController(); 38 | bool _emailValid = true; 39 | bool _passwordValid = true; 40 | 41 | @override 42 | void dispose() { 43 | debounce?.cancel(); 44 | _emailController.dispose(); 45 | _passwordController.dispose(); 46 | super.dispose(); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Scaffold( 52 | appBar: AppBar(), 53 | body: Padding( 54 | padding: const EdgeInsets.all(16.0), 55 | child: Column( 56 | children: [ 57 | const Text( 58 | 'Sign In', 59 | style: TextStyle( 60 | fontSize: 32.0, 61 | fontWeight: FontWeight.bold, 62 | ), 63 | ), 64 | const SizedBox(height: 16.0), 65 | TextFormField( 66 | controller: _emailController, 67 | decoration: InputDecoration( 68 | labelText: 'Email', 69 | errorText: _emailValid ? null : 'Please enter a valid email', 70 | ), 71 | keyboardType: TextInputType.emailAddress, 72 | onChanged: (String value) { 73 | if (debounce?.isActive ?? false) debounce?.cancel(); 74 | debounce = Timer(const Duration(milliseconds: 500), () { 75 | setState(() { 76 | _emailValid = validateEmail(value) == null; 77 | }); 78 | }); 79 | }, 80 | ), 81 | TextFormField( 82 | controller: _passwordController, 83 | decoration: InputDecoration( 84 | labelText: 'Password', 85 | errorText: _passwordValid 86 | ? null 87 | : 'Password must be at least 8 characters long', 88 | ), 89 | obscureText: true, 90 | onChanged: (String value) { 91 | if (debounce?.isActive ?? false) debounce?.cancel(); 92 | debounce = Timer(const Duration(milliseconds: 500), () { 93 | setState(() { 94 | _passwordValid = validatePassword(value) == null; 95 | }); 96 | }); 97 | }, 98 | ), 99 | const SizedBox(height: 8.0), 100 | ElevatedButton(onPressed: () {}, child: const Text('Submit')) 101 | ], 102 | ), 103 | ), 104 | ); 105 | } 106 | 107 | String? validateEmail(String value) { 108 | if (value.isEmpty) { 109 | return 'Please enter your email'; 110 | } 111 | if (!RegExp(r'^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$') 112 | .hasMatch(value)) { 113 | return 'Please enter a valid email'; 114 | } 115 | return null; 116 | } 117 | 118 | String? validatePassword(String value) { 119 | if (value.isEmpty) { 120 | return 'Please enter your password'; 121 | } 122 | if (value.length < 8) { 123 | return 'Password must be at least 8 characters long'; 124 | } 125 | return null; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /lib/02_interactive_drawing_canvas.dart: -------------------------------------------------------------------------------- 1 | // Interactive Drawing Canvas by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | 6 | void main() { 7 | runApp(const MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | const MyApp({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | theme: ThemeData.light(useMaterial3: true), 17 | home: const DrawingCanvas(), 18 | ); 19 | } 20 | } 21 | 22 | class DrawingCanvas extends StatefulWidget { 23 | const DrawingCanvas({super.key}); 24 | 25 | @override 26 | State createState() => _DrawingCanvasState(); 27 | } 28 | 29 | class _DrawingCanvasState extends State { 30 | List offsets = []; 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | return Scaffold( 35 | body: GestureDetector( 36 | onPanUpdate: (DragUpdateDetails details) { 37 | setState(() { 38 | offsets.add(details.globalPosition); 39 | }); 40 | }, 41 | onPanEnd: (DragEndDetails details) => setState(() {}), 42 | child: CustomPaint( 43 | painter: Draw(offsets: offsets), 44 | size: Size.infinite, 45 | ), 46 | ), 47 | floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, 48 | floatingActionButton: FloatingActionButton.extended( 49 | icon: const Icon(Icons.clear), 50 | label: const Text('Clear'), 51 | onPressed: () { 52 | setState(() => offsets.clear()); 53 | }, 54 | ), 55 | ); 56 | } 57 | } 58 | 59 | class Draw extends CustomPainter { 60 | const Draw({required this.offsets}); 61 | 62 | final List offsets; 63 | 64 | @override 65 | void paint(Canvas canvas, Size size) { 66 | Paint paint = Paint(); 67 | paint.color = Colors.blue.shade900; 68 | paint.strokeWidth = 5.0; 69 | 70 | for (int i = 0; i < offsets.length - 1; i++) { 71 | canvas.drawLine(offsets[i], offsets[i + 1], paint); 72 | } 73 | } 74 | 75 | @override 76 | bool shouldRepaint(Draw oldDelegate) => true; 77 | } 78 | -------------------------------------------------------------------------------- /lib/03_bar_charts.dart: -------------------------------------------------------------------------------- 1 | // Bar Charts with Flutter by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | 6 | void main() { 7 | runApp(const MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | const MyApp({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | theme: ThemeData.light(useMaterial3: true), 17 | home: BarChart( 18 | colors: [ 19 | Colors.deepOrange.shade100, 20 | Colors.deepOrange.shade200, 21 | Colors.deepOrange.shade300, 22 | Colors.deepOrange.shade400, 23 | ], 24 | ), 25 | ); 26 | } 27 | } 28 | 29 | const defaultSpacing = 16.0; 30 | 31 | class BarChart extends StatelessWidget { 32 | const BarChart({ 33 | Key? key, 34 | this.colors, 35 | this.values = const [200, 100, 400, 30], 36 | }) : super(key: key); 37 | 38 | final List? colors; 39 | final List values; 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | return Scaffold( 44 | appBar: AppBar(title: const Text('Bar Chart')), 45 | body: Padding( 46 | padding: const EdgeInsets.all(16.0), 47 | child: Column( 48 | mainAxisAlignment: MainAxisAlignment.center, 49 | children: [ 50 | LayoutBuilder( 51 | builder: (context, constraints) { 52 | final barWidth = 53 | (constraints.maxWidth - defaultSpacing * values.length) / 54 | values.length; 55 | return CustomPaint( 56 | size: Size(constraints.maxWidth, 200), 57 | painter: BarChartPainter( 58 | values: values, 59 | colors: colors ?? 60 | List.generate(values.length, (i) => i + 1).map( 61 | (e) { 62 | final opacity = e / values.length; 63 | return Theme.of(context) 64 | .colorScheme 65 | .primary 66 | .withOpacity(opacity); 67 | }, 68 | ).toList(), 69 | barWidth: barWidth, 70 | ), 71 | ); 72 | }, 73 | ), 74 | ], 75 | ), 76 | ), 77 | ); 78 | } 79 | } 80 | 81 | class BarChartPainter extends CustomPainter { 82 | BarChartPainter({ 83 | required this.values, 84 | required this.colors, 85 | this.barWidth = 24.0, 86 | }); 87 | 88 | final List values; 89 | final List colors; 90 | final double barWidth; 91 | 92 | @override 93 | void paint(Canvas canvas, Size size) { 94 | // Find the maximum value in the list of values. 95 | double max = values.reduce((a, b) => a > b ? a : b); 96 | 97 | // Paint object for drawing the axes. 98 | final axisPaint = Paint() 99 | ..color = Colors.black 100 | ..strokeWidth = 1.0; 101 | 102 | // Draw the y-axis. 103 | canvas.drawLine( 104 | const Offset(0, 0), 105 | Offset(0, size.height), 106 | axisPaint, 107 | ); 108 | 109 | // Draw the x-axis. 110 | canvas.drawLine( 111 | Offset(0, size.height), 112 | Offset(size.width, size.height), 113 | axisPaint, 114 | ); 115 | 116 | // Loop through each value and draw a bar for it. 117 | for (int i = 0; i < values.length; i++) { 118 | // Paint object for drawing the bar. 119 | final paint = Paint() 120 | ..color = colors[i] 121 | ..style = PaintingStyle.fill; 122 | 123 | // Calculate the total space for each bar, including the space between bars. 124 | final totalSpace = barWidth + defaultSpacing; 125 | // Calculate the height of the bar based on its value. 126 | final barHeight = values[i] / max * (size.height - defaultSpacing); 127 | // Calculate the left position of the bar to center it within its allocated 128 | // space. 129 | final barLeft = i * totalSpace + totalSpace / 2 - barWidth / 2; 130 | 131 | // Create a rectangle representing the bar. 132 | final barRect = Rect.fromLTWH( 133 | barLeft, 134 | size.height - barHeight, 135 | barWidth, 136 | barHeight, 137 | ); 138 | 139 | // Draw the bar on the canvas. 140 | canvas.drawRect(barRect, paint); 141 | 142 | // Create a TextPainter for drawing the label. 143 | final labelPainter = TextPainter( 144 | text: TextSpan( 145 | text: '${(values[i])}', 146 | style: const TextStyle(color: Colors.black, fontSize: 16), 147 | ), 148 | textDirection: TextDirection.ltr, 149 | ); 150 | 151 | // Layout the text and paint it on the canvas. 152 | labelPainter.layout(); 153 | labelPainter.paint( 154 | canvas, 155 | Offset( 156 | i * (barWidth + defaultSpacing) + (barWidth / 2 - defaultSpacing / 2), 157 | size.height, 158 | ), 159 | ); 160 | } 161 | } 162 | 163 | @override 164 | bool shouldRepaint(CustomPainter oldDelegate) => true; 165 | } 166 | -------------------------------------------------------------------------------- /lib/04_copy_and_paste.dart: -------------------------------------------------------------------------------- 1 | // Copy & Paste in Flutter apps by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter/services.dart' show Clipboard, ClipboardData; 6 | 7 | void main() { 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | theme: ThemeData.light(useMaterial3: true), 18 | home: const CopyAndPaste(), 19 | ); 20 | } 21 | } 22 | 23 | class CopyAndPaste extends StatelessWidget { 24 | const CopyAndPaste({Key? key}) : super(key: key); 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | final controller1 = TextEditingController(); 29 | final controller2 = TextEditingController(); 30 | 31 | return Scaffold( 32 | appBar: AppBar(title: const Text('Copy & Paste')), 33 | body: Padding( 34 | padding: const EdgeInsets.all(16.0), 35 | child: Column( 36 | children: [ 37 | SelectableText( 38 | 'This is a string that you can Select and Copy', 39 | style: Theme.of(context) 40 | .textTheme 41 | .headlineMedium! 42 | .copyWith(color: Theme.of(context).colorScheme.primary), 43 | textAlign: TextAlign.center, 44 | ), 45 | const SizedBox(height: 32.0), 46 | InkWell( 47 | onTap: () { 48 | Clipboard.setData( 49 | const ClipboardData( 50 | text: 'This is a string that you can Tap and Copy', 51 | ), 52 | ); 53 | }, 54 | child: Text( 55 | 'This is a string that you can Tap and Copy', 56 | style: Theme.of(context) 57 | .textTheme 58 | .headlineMedium! 59 | .copyWith(color: Theme.of(context).colorScheme.secondary), 60 | textAlign: TextAlign.center, 61 | ), 62 | ), 63 | const SizedBox(height: 32.0), 64 | TextFormField( 65 | controller: controller1, 66 | decoration: const InputDecoration( 67 | hintText: 'Tap here to paste manually', 68 | ), 69 | ), 70 | const SizedBox(height: 32.0), 71 | TextFormField( 72 | controller: controller2, 73 | decoration: const InputDecoration( 74 | hintText: 'Tap here to paste automatically', 75 | ), 76 | onTap: () async { 77 | if (await Clipboard.hasStrings()) { 78 | final data = await Clipboard.getData('text/plain'); 79 | final text = data?.text; 80 | if (text != null) { 81 | controller2.text = text; 82 | } 83 | } 84 | }, 85 | ) 86 | ], 87 | ), 88 | ), 89 | ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/05_lottie_animations_with_color_filter.dart: -------------------------------------------------------------------------------- 1 | // Lottie Animation in Flutter apps by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:lottie/lottie.dart'; 6 | 7 | void main() { 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | theme: ThemeData.light(useMaterial3: true), 18 | home: const LottieAnimationExample(), 19 | ); 20 | } 21 | } 22 | 23 | class LottieAnimationExample extends StatelessWidget { 24 | const LottieAnimationExample({super.key}); 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Scaffold( 29 | appBar: AppBar( 30 | title: const Text('Animations with Lottie'), 31 | ), 32 | body: Column( 33 | children: [ 34 | ColorFiltered( 35 | colorFilter: ColorFilter.mode( 36 | Theme.of(context).colorScheme.primary, 37 | BlendMode.color, 38 | ), 39 | child: Lottie.asset( 40 | 'assets/message_bubble.json', 41 | repeat: true, 42 | reverse: true, 43 | height: 300, 44 | width: double.infinity, 45 | ), 46 | ), 47 | ], 48 | ), 49 | ); 50 | } 51 | } 52 | 53 | // https://lottiefiles.com/animations/pizza-VnnHMy9OOV 54 | -------------------------------------------------------------------------------- /lib/06_carousel_slider.dart: -------------------------------------------------------------------------------- 1 | // Carousel Slider with dots indication in a Flutter app by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:carousel_slider/carousel_slider.dart'; 5 | import 'package:dots_indicator/dots_indicator.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | void main() { 9 | runApp(const MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | theme: ThemeData.light(useMaterial3: true), 19 | home: const CarouselSliderWithDots(), 20 | ); 21 | } 22 | } 23 | 24 | class CarouselSliderWithDots extends StatefulWidget { 25 | const CarouselSliderWithDots({ 26 | super.key, 27 | this.items = const [ 28 | 'https://images.unsplash.com/photo-1688920556232-321bd176d0b4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80', 29 | 'https://images.unsplash.com/photo-1689085781839-2e1ff15cb9fe?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80', 30 | 'https://images.unsplash.com/photo-1688980034676-7e8ee518e75a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=735&q=80', 31 | ], 32 | }); 33 | 34 | final List items; 35 | 36 | @override 37 | State createState() => _CarouselSliderWithDotsState(); 38 | } 39 | 40 | class _CarouselSliderWithDotsState extends State { 41 | late CarouselController controller; 42 | int currentIndex = 0; 43 | 44 | @override 45 | void initState() { 46 | controller = CarouselController(); 47 | super.initState(); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Scaffold( 53 | appBar: AppBar(title: const Text('Carousel with Dots Indicator')), 54 | body: Stack( 55 | alignment: AlignmentDirectional.topCenter, 56 | children: [ 57 | CarouselSlider( 58 | carouselController: controller, 59 | items: widget.items 60 | .map( 61 | (item) => Image.network( 62 | item, 63 | fit: BoxFit.cover, 64 | width: double.infinity, 65 | ), 66 | ) 67 | .toList(), 68 | options: CarouselOptions( 69 | height: 400, 70 | autoPlay: true, 71 | onPageChanged: (index, reason) { 72 | setState(() { 73 | currentIndex = index; 74 | }); 75 | }, 76 | ), 77 | ), 78 | Positioned( 79 | bottom: 8.0, 80 | child: DotsIndicator( 81 | dotsCount: widget.items.length, 82 | position: currentIndex, 83 | onTap: (index) { 84 | controller.animateToPage(index); 85 | }, 86 | decorator: DotsDecorator( 87 | color: Colors.white, 88 | activeColor: Colors.amber, 89 | size: const Size.square(12.0), 90 | activeSize: const Size(24.0, 12.0), 91 | activeShape: RoundedRectangleBorder( 92 | borderRadius: BorderRadius.circular(12.0), 93 | ), 94 | ), 95 | ), 96 | ), 97 | ], 98 | ), 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/07_avatar_stack_animation.dart: -------------------------------------------------------------------------------- 1 | // Animations with flutter_animatie by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_animate/flutter_animate.dart'; 6 | 7 | void main() { 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | debugShowCheckedModeBanner: false, 18 | theme: ThemeData.light(useMaterial3: true), 19 | home: const AvatarStackAnimation(), 20 | ); 21 | } 22 | } 23 | 24 | class AvatarStackAnimation extends StatelessWidget { 25 | const AvatarStackAnimation({super.key}); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | body: Column( 31 | mainAxisAlignment: MainAxisAlignment.center, 32 | crossAxisAlignment: CrossAxisAlignment.center, 33 | children: [ 34 | const Text('Animations with'), 35 | Text( 36 | 'flutter_animate', 37 | style: Theme.of(context).textTheme.headlineSmall, 38 | ), 39 | const AvatarStack( 40 | avatars: [ 41 | 'https://images.unsplash.com/photo-1688920556232-321bd176d0b4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80', 42 | 'https://images.unsplash.com/photo-1689085781839-2e1ff15cb9fe?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80', 43 | 'https://images.unsplash.com/photo-1688980034676-7e8ee518e75a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=735&q=80', 44 | ], 45 | ), 46 | ], 47 | ), 48 | ); 49 | } 50 | } 51 | 52 | class AvatarStack extends StatelessWidget { 53 | const AvatarStack({ 54 | super.key, 55 | required this.avatars, 56 | this.stackHeight = 120, 57 | this.extraParticipantsCount, 58 | }); 59 | 60 | final List avatars; 61 | final double stackHeight; 62 | final int? extraParticipantsCount; 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return SizedBox( 67 | height: stackHeight, 68 | child: Stack( 69 | children: List.generate( 70 | avatars.length, 71 | (index) => Align( 72 | alignment: Alignment.center, 73 | child: Transform.translate( 74 | offset: Offset((index - 1) * 50.0, 0), 75 | child: Avatar(imageUrl: avatars[index]) 76 | .animate( 77 | delay: const Duration( 78 | milliseconds: 500, 79 | ), 80 | ) 81 | .fadeIn( 82 | delay: Duration( 83 | milliseconds: index * 100, 84 | ), 85 | ) 86 | .slide( 87 | begin: const Offset(0.5, 0), 88 | duration: const Duration( 89 | milliseconds: 200, 90 | ), 91 | curve: Curves.easeOut, 92 | delay: Duration( 93 | milliseconds: index * 100, 94 | ), 95 | ) 96 | .animate( 97 | onPlay: (controller) { 98 | controller.repeat(); 99 | }, 100 | ).shimmer( 101 | duration: 2400.ms, 102 | ), 103 | ), 104 | ), 105 | ), 106 | ), 107 | ); 108 | } 109 | } 110 | 111 | class Avatar extends StatelessWidget { 112 | const Avatar({ 113 | super.key, 114 | required this.imageUrl, 115 | this.radius = 50, 116 | this.child, 117 | }); 118 | 119 | final String imageUrl; 120 | final int radius; 121 | final Widget? child; 122 | 123 | @override 124 | Widget build(BuildContext context) { 125 | return CircleAvatar( 126 | radius: radius.toDouble() + 2, 127 | backgroundColor: Colors.white, 128 | child: CircleAvatar( 129 | radius: radius.toDouble(), 130 | backgroundImage: NetworkImage(imageUrl), 131 | child: child, 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/08_text_and_image_animation.dart: -------------------------------------------------------------------------------- 1 | // More animations with flutter_animate by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:carousel_slider/carousel_slider.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_animate/flutter_animate.dart'; 7 | 8 | void main() { 9 | runApp(const MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | debugShowCheckedModeBanner: false, 19 | theme: ThemeData.light(useMaterial3: true), 20 | home: const TextAndImageAnimation(), 21 | ); 22 | } 23 | } 24 | 25 | class TextAndImageAnimation extends StatelessWidget { 26 | const TextAndImageAnimation({Key? key}) : super(key: key); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | // Records 31 | List<(String city, String imageUrl)> destinations = [ 32 | ( 33 | 'New York', 34 | 'https://images.unsplash.com/photo-1500916434205-0c77489c6cf7?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=687&q=80', 35 | ), 36 | ( 37 | 'Paris', 38 | 'https://images.unsplash.com/photo-1499856871958-5b9627545d1a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1420&q=80', 39 | ), 40 | ( 41 | 'Tokyo', 42 | 'https://images.unsplash.com/photo-1513407030348-c983a97b98d8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1472&q=80', 43 | ), 44 | ( 45 | 'Sydney', 46 | 'https://images.unsplash.com/photo-1506973035872-a4ec16b8e8d9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80', 47 | ) 48 | ]; 49 | 50 | final size = MediaQuery.of(context).size; 51 | final theme = Theme.of(context); 52 | return Scaffold( 53 | appBar: AppBar(), 54 | body: Column( 55 | crossAxisAlignment: CrossAxisAlignment.center, 56 | children: [ 57 | Text( 58 | 'Let\'s choose your travel route', 59 | textAlign: TextAlign.center, 60 | style: theme.textTheme.displaySmall!.copyWith( 61 | fontWeight: FontWeight.bold, 62 | ), 63 | ) 64 | .animate(onPlay: (controller) => controller.repeat()) 65 | .shimmer( 66 | duration: 2400.ms, 67 | color: theme.colorScheme.primary, 68 | ) 69 | .animate() 70 | .fadeIn(duration: 1200.ms, curve: Curves.easeOutQuad) 71 | .slide(), 72 | const Spacer(), 73 | CarouselSlider( 74 | options: CarouselOptions( 75 | height: size.height * 0.66, 76 | enlargeCenterPage: true, 77 | ), 78 | items: destinations.map( 79 | (destination) { 80 | return Card( 81 | shape: RoundedRectangleBorder( 82 | borderRadius: BorderRadius.circular(0.0), 83 | ), 84 | child: Stack( 85 | children: [ 86 | Positioned.fill( 87 | child: Image.network( 88 | destination.$2, 89 | fit: BoxFit.cover, 90 | ), 91 | ).animate().shimmer(duration: 1200.ms), 92 | const SizedBox(height: 8.0), 93 | Align( 94 | alignment: Alignment.center, 95 | child: Text( 96 | destination.$1, 97 | textAlign: TextAlign.center, 98 | style: theme.textTheme.displayLarge!.copyWith( 99 | fontWeight: FontWeight.bold, 100 | color: theme.colorScheme.onPrimary, 101 | ), 102 | ), 103 | ), 104 | ], 105 | ), 106 | ); 107 | }, 108 | ).toList(), 109 | ).animate().fadeIn( 110 | duration: 1200.ms, 111 | curve: Curves.easeOutQuad, 112 | ), 113 | const Spacer(), 114 | ], 115 | ), 116 | ); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /lib/09_speech_to_text_with_whisper.dart: -------------------------------------------------------------------------------- 1 | // Speech to Text with OpenAI's Whisper by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'dart:convert'; 5 | import 'dart:io'; 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter/services.dart'; 9 | import 'package:http/http.dart' as http; 10 | import 'package:http_parser/http_parser.dart'; 11 | 12 | const API_KEY = 'API_KEY'; 13 | 14 | void main() { 15 | return runApp(const MyApp()); 16 | } 17 | 18 | class MyApp extends StatelessWidget { 19 | const MyApp({super.key}); 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return MaterialApp( 24 | title: 'Speech to Text', 25 | theme: ThemeData.light(useMaterial3: true), 26 | home: const SpeechToTextWidget(), 27 | ); 28 | } 29 | } 30 | 31 | class SpeechToTextWidget extends StatefulWidget { 32 | const SpeechToTextWidget({super.key}); 33 | 34 | @override 35 | State createState() => _SpeechToTextWidgetState(); 36 | } 37 | 38 | class _SpeechToTextWidgetState extends State { 39 | final client = SpeechToTextApiClient(); 40 | var _transcript = ''; 41 | var _isLoading = false; 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | appBar: AppBar( 47 | title: const Text('Speech to Text Conversion'), 48 | ), 49 | body: Padding( 50 | padding: const EdgeInsets.all(8.0), 51 | child: Center( 52 | child: _isLoading 53 | ? const CircularProgressIndicator() 54 | : _transcript != '' 55 | ? Text(_transcript) 56 | : IconButton( 57 | style: IconButton.styleFrom( 58 | backgroundColor: 59 | Theme.of(context).colorScheme.primaryContainer, 60 | ), 61 | onPressed: () async { 62 | const path = 'assets/audios/example_audio.mp3'; 63 | final audio = await rootBundle.load(path); 64 | setState(() => _isLoading = true); 65 | 66 | final results = await client.convertSpeechToText( 67 | audio: audio, 68 | filename: 'audio_to_convert.mp3', 69 | ); 70 | 71 | setState(() { 72 | _transcript = results['text']; 73 | _isLoading = false; 74 | }); 75 | }, 76 | icon: Icon( 77 | Icons.mic, 78 | size: 80, 79 | color: Theme.of(context).colorScheme.primary, 80 | ), 81 | ), 82 | ), 83 | ), 84 | ); 85 | } 86 | } 87 | 88 | // IMPORTANT: Storing an API key on the client is not secure. The example 89 | // is only intended for demonstration purposes. Consider interacting with 90 | // the OpenAI API using a backend server to keep your API key safe! 91 | 92 | class SpeechToTextApiClient { 93 | static const String baseUrl = 'https://api.openai.com'; 94 | 95 | /// POST /v1/audio/transcriptions 96 | /// Used to upload an MP3 file to be converted to text. 97 | /// Requires a filePath to the local MP3 file. 98 | Future> convertSpeechToText({ 99 | required String filename, 100 | required ByteData audio, 101 | String model = 'whisper-1', 102 | }) async { 103 | final uri = Uri.parse('$baseUrl/v1/audio/transcriptions'); 104 | 105 | // Create a multipart request. 106 | var request = http.MultipartRequest('POST', uri); 107 | 108 | // Set the authorization header. 109 | request.headers[HttpHeaders.authorizationHeader] = 'Bearer $API_KEY'; 110 | 111 | var multipartFile = http.MultipartFile.fromBytes( 112 | 'file', 113 | audio.buffer.asUint8List(), 114 | filename: filename, 115 | contentType: MediaType('audio', 'mpeg'), 116 | ); 117 | 118 | // Add the model field. 119 | request.fields['model'] = model; 120 | request.files.add(multipartFile); 121 | 122 | // Send the request to the server. 123 | http.Response response = await http.Response.fromStream( 124 | await request.send(), 125 | ); 126 | 127 | final body = jsonDecode(response.body); 128 | 129 | if (response.statusCode != HttpStatus.ok) { 130 | throw Exception('${response.statusCode}, error: ${body['message']}'); 131 | } 132 | 133 | return body; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/10_popover.dart: -------------------------------------------------------------------------------- 1 | // Popovers with the popover package by maxonflutter 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:lottie/lottie.dart'; 6 | import 'package:popover/popover.dart'; 7 | 8 | void main() { 9 | runApp(const MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | debugShowCheckedModeBanner: false, 19 | theme: ThemeData.light(useMaterial3: true), 20 | home: const PopoverExample(), 21 | ); 22 | } 23 | } 24 | 25 | class PopoverExample extends StatelessWidget { 26 | const PopoverExample({Key? key}) : super(key: key); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | List< 31 | ( 32 | String name, 33 | String path, 34 | )> popoverOptions = [ 35 | ('Option 1', '/option-1'), 36 | ('Option 2', '/option-2'), 37 | ('Option 3', '/option-3') 38 | ]; 39 | 40 | return Scaffold( 41 | appBar: AppBar( 42 | title: const Text('Popover Example'), 43 | centerTitle: true, 44 | actions: [ 45 | Container( 46 | width: 40, 47 | height: 40, 48 | decoration: BoxDecoration( 49 | color: Theme.of(context).colorScheme.primaryContainer, 50 | shape: BoxShape.circle, 51 | ), 52 | // The Builder widget helps us to add another context above its 53 | // children. Without the Builder, the context might refer to a 54 | // widget above the Container in the widget tree, which could 55 | // potentially cause issues when trying to show the popover. 56 | child: Builder( 57 | builder: (context) { 58 | return GestureDetector( 59 | onTap: () => _showPopover(context, popoverOptions), 60 | child: const Icon(Icons.more_vert), 61 | ); 62 | }, 63 | ), 64 | ), 65 | const SizedBox(width: 16.0), 66 | ], 67 | ), 68 | body: Column( 69 | crossAxisAlignment: CrossAxisAlignment.center, 70 | mainAxisAlignment: MainAxisAlignment.center, 71 | children: [ 72 | ColorFiltered( 73 | colorFilter: ColorFilter.mode( 74 | Theme.of(context).colorScheme.primary, 75 | BlendMode.color, 76 | ), 77 | child: Lottie.asset( 78 | 'assets/message_bubble.json', 79 | repeat: true, 80 | reverse: true, 81 | height: 300, 82 | width: double.infinity, 83 | ), 84 | ), 85 | ], 86 | ), 87 | ); 88 | } 89 | 90 | Future _showPopover( 91 | BuildContext context, 92 | List<(String, String)> popoverOptions, 93 | ) { 94 | Size size = MediaQuery.sizeOf(context); 95 | return showPopover( 96 | context: context, 97 | backgroundColor: Colors.white, 98 | radius: 16.0, 99 | bodyBuilder: (context) => ListView( 100 | shrinkWrap: true, 101 | padding: EdgeInsets.zero, 102 | children: popoverOptions.map((option) { 103 | return ListTile( 104 | title: Text(option.$1), 105 | onTap: () { 106 | Navigator.pushNamed(context, option.$2); 107 | }, 108 | ); 109 | }).toList(), 110 | ), 111 | 112 | direction: PopoverDirection.top, 113 | width: size.width * 0.5, 114 | arrowHeight: 16.0, 115 | arrowWidth: 16.0, 116 | // onPop: () {}, 117 | ); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /lib/11_app_bar_banner_with_animation.dart: -------------------------------------------------------------------------------- 1 | // App bar with an animated banner 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'dart:ui'; 5 | 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_animate/flutter_animate.dart'; 8 | import 'package:url_launcher/url_launcher.dart'; 9 | 10 | void main() { 11 | runApp(const MyApp()); 12 | } 13 | 14 | class MyApp extends StatelessWidget { 15 | const MyApp({super.key}); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return MaterialApp( 20 | debugShowCheckedModeBanner: false, 21 | theme: ThemeData.light(useMaterial3: true), 22 | home: const AppBarWithAnimatedBanner(), 23 | ); 24 | } 25 | } 26 | 27 | class AppBarWithAnimatedBanner extends StatelessWidget { 28 | const AppBarWithAnimatedBanner({Key? key}) : super(key: key); 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | appBar: AppBar( 34 | backgroundColor: Colors.black, 35 | title: Image.asset( 36 | 'assets/images/junior_logo_white.png', 37 | height: 48.0, 38 | ), 39 | bottom: const AppBarBanner(), 40 | ), 41 | body: Container(), 42 | ); 43 | } 44 | } 45 | 46 | class AppBarBanner extends StatelessWidget implements PreferredSizeWidget { 47 | const AppBarBanner({super.key}); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Container( 52 | height: 56.0, 53 | width: double.infinity, 54 | color: const Color(0XFF982043), 55 | child: InkWell( 56 | onTap: () async { 57 | await launchUrl( 58 | Uri.parse( 59 | 'https://junior.atomsbox.com', 60 | ), 61 | ); 62 | }, 63 | child: Row( 64 | mainAxisAlignment: MainAxisAlignment.center, 65 | children: [ 66 | Text( 67 | 'Junior AI works in your GitHub. Install it now!', 68 | style: Theme.of(context) 69 | .textTheme 70 | .bodyMedium! 71 | .copyWith(color: Colors.white), 72 | ), 73 | const SizedBox(width: 8.0), 74 | const Icon(Icons.launch), 75 | ], 76 | ), 77 | ), 78 | ) 79 | .animate( 80 | onComplete: (controller) => controller.repeat(), 81 | ) 82 | .shimmer( 83 | duration: const Duration(milliseconds: 2000), 84 | delay: const Duration(milliseconds: 1000), 85 | ); 86 | } 87 | 88 | @override 89 | Size get preferredSize => const Size.fromHeight(56.0); 90 | } 91 | -------------------------------------------------------------------------------- /lib/12_enhanced_enums.dart: -------------------------------------------------------------------------------- 1 | // Enhanced Enums 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | // Enums are a special type of class that represents a group of constants (unchangeable variables, like final variables). 5 | // enum Fruit { apple, banana, orange } 6 | 7 | mixin VitaminCContent { 8 | bool get hasHighVitaminC; 9 | } 10 | 11 | // Enhanced Enums can have properties and methods. 12 | enum Fruit with VitaminCContent { 13 | apple('Red', false), 14 | banana('Yellow', false), 15 | orange('Orange', true); 16 | 17 | final String color; 18 | final bool hasHighVitaminC; 19 | 20 | const Fruit( 21 | this.color, 22 | this.hasHighVitaminC, 23 | ); 24 | 25 | String describeColor() => 'The color of this fruit is $color.'; 26 | } 27 | 28 | // Enhanced Enums can have constructors and generic types. 29 | enum Box { 30 | small(10), 31 | medium(15.5), 32 | large('20'); 33 | 34 | final T dimension; 35 | 36 | const Box(this.dimension); 37 | } 38 | -------------------------------------------------------------------------------- /lib/13_2d_scrolling.dart: -------------------------------------------------------------------------------- 1 | // 2D Scrolling from: https://dartpad.dev/?id=4424936c57ed13093eb389123383e894 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file 5 | // for details. All rights reserved. Use of this source code is governed by a 6 | // BSD-style license that can be found in the LICENSE file. 7 | 8 | import 'dart:math' as math; 9 | 10 | import 'package:flutter/foundation.dart'; 11 | import 'package:flutter/gestures.dart'; 12 | import 'package:flutter/material.dart'; 13 | import 'package:flutter/rendering.dart'; 14 | 15 | void main() { 16 | runApp(const MyApp()); 17 | } 18 | 19 | class MyApp extends StatelessWidget { 20 | const MyApp({super.key}); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return MaterialApp( 25 | debugShowCheckedModeBanner: false, 26 | theme: ThemeData.light(useMaterial3: true), 27 | scrollBehavior: const MaterialScrollBehavior().copyWith( 28 | dragDevices: PointerDeviceKind.values.toSet(), 29 | ), 30 | home: const TwoDimensionsScrollingExample(), 31 | ); 32 | } 33 | } 34 | 35 | class TwoDimensionsScrollingExample extends StatelessWidget { 36 | const TwoDimensionsScrollingExample({super.key}); 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Scaffold( 41 | appBar: AppBar(title: const Text('2D Scrolling')), 42 | body: TwoDimensionalGridView( 43 | diagonalDragBehavior: DiagonalDragBehavior.free, 44 | delegate: TwoDimensionalChildBuilderDelegate( 45 | maxXIndex: 9, 46 | maxYIndex: 9, 47 | builder: (BuildContext context, ChildVicinity vicinity) { 48 | return Container( 49 | color: vicinity.xIndex.isEven && vicinity.yIndex.isEven 50 | ? Colors.amber[50] 51 | : (vicinity.xIndex.isOdd && vicinity.yIndex.isOdd 52 | ? Colors.purple[50] 53 | : null), 54 | height: 200, 55 | width: 200, 56 | child: Center( 57 | child: Text( 58 | 'Row ${vicinity.yIndex}: Column ${vicinity.xIndex}', 59 | ), 60 | ), 61 | ); 62 | }), 63 | ), 64 | ); 65 | } 66 | } 67 | 68 | class TwoDimensionalGridView extends TwoDimensionalScrollView { 69 | const TwoDimensionalGridView({ 70 | super.key, 71 | super.primary, 72 | super.mainAxis = Axis.vertical, 73 | super.verticalDetails = const ScrollableDetails.vertical(), 74 | super.horizontalDetails = const ScrollableDetails.horizontal(), 75 | required TwoDimensionalChildBuilderDelegate delegate, 76 | super.cacheExtent, 77 | super.diagonalDragBehavior = DiagonalDragBehavior.none, 78 | super.dragStartBehavior = DragStartBehavior.start, 79 | super.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, 80 | super.clipBehavior = Clip.hardEdge, 81 | }) : super(delegate: delegate); 82 | 83 | @override 84 | Widget buildViewport( 85 | BuildContext context, 86 | ViewportOffset verticalOffset, 87 | ViewportOffset horizontalOffset, 88 | ) { 89 | return TwoDimensionalGridViewport( 90 | horizontalOffset: horizontalOffset, 91 | horizontalAxisDirection: horizontalDetails.direction, 92 | verticalOffset: verticalOffset, 93 | verticalAxisDirection: verticalDetails.direction, 94 | mainAxis: mainAxis, 95 | delegate: delegate as TwoDimensionalChildBuilderDelegate, 96 | cacheExtent: cacheExtent, 97 | clipBehavior: clipBehavior, 98 | ); 99 | } 100 | } 101 | 102 | class TwoDimensionalGridViewport extends TwoDimensionalViewport { 103 | const TwoDimensionalGridViewport({ 104 | super.key, 105 | required super.verticalOffset, 106 | required super.verticalAxisDirection, 107 | required super.horizontalOffset, 108 | required super.horizontalAxisDirection, 109 | required TwoDimensionalChildBuilderDelegate super.delegate, 110 | required super.mainAxis, 111 | super.cacheExtent, 112 | super.clipBehavior = Clip.hardEdge, 113 | }); 114 | 115 | @override 116 | RenderTwoDimensionalViewport createRenderObject(BuildContext context) { 117 | return RenderTwoDimensionalGridViewport( 118 | horizontalOffset: horizontalOffset, 119 | horizontalAxisDirection: horizontalAxisDirection, 120 | verticalOffset: verticalOffset, 121 | verticalAxisDirection: verticalAxisDirection, 122 | mainAxis: mainAxis, 123 | delegate: delegate as TwoDimensionalChildBuilderDelegate, 124 | childManager: context as TwoDimensionalChildManager, 125 | cacheExtent: cacheExtent, 126 | clipBehavior: clipBehavior, 127 | ); 128 | } 129 | 130 | @override 131 | void updateRenderObject( 132 | BuildContext context, 133 | RenderTwoDimensionalGridViewport renderObject, 134 | ) { 135 | renderObject 136 | ..horizontalOffset = horizontalOffset 137 | ..horizontalAxisDirection = horizontalAxisDirection 138 | ..verticalOffset = verticalOffset 139 | ..verticalAxisDirection = verticalAxisDirection 140 | ..mainAxis = mainAxis 141 | ..delegate = delegate 142 | ..cacheExtent = cacheExtent 143 | ..clipBehavior = clipBehavior; 144 | } 145 | } 146 | 147 | class RenderTwoDimensionalGridViewport extends RenderTwoDimensionalViewport { 148 | RenderTwoDimensionalGridViewport({ 149 | required super.horizontalOffset, 150 | required super.horizontalAxisDirection, 151 | required super.verticalOffset, 152 | required super.verticalAxisDirection, 153 | required TwoDimensionalChildBuilderDelegate delegate, 154 | required super.mainAxis, 155 | required super.childManager, 156 | super.cacheExtent, 157 | super.clipBehavior = Clip.hardEdge, 158 | }) : super(delegate: delegate); 159 | 160 | @override 161 | void layoutChildSequence() { 162 | final double horizontalPixels = horizontalOffset.pixels; 163 | final double verticalPixels = verticalOffset.pixels; 164 | final double viewportWidth = viewportDimension.width + cacheExtent; 165 | final double viewportHeight = viewportDimension.height + cacheExtent; 166 | final TwoDimensionalChildBuilderDelegate builderDelegate = 167 | delegate as TwoDimensionalChildBuilderDelegate; 168 | 169 | final int maxRowIndex = builderDelegate.maxYIndex!; 170 | final int maxColumnIndex = builderDelegate.maxXIndex!; 171 | 172 | final int leadingColumn = math.max((horizontalPixels / 200).floor(), 0); 173 | final int leadingRow = math.max((verticalPixels / 200).floor(), 0); 174 | final int trailingColumn = math.min( 175 | ((horizontalPixels + viewportWidth) / 200).ceil(), 176 | maxColumnIndex, 177 | ); 178 | final int trailingRow = math.min( 179 | ((verticalPixels + viewportHeight) / 200).ceil(), 180 | maxRowIndex, 181 | ); 182 | 183 | double xLayoutOffset = (leadingColumn * 200) - horizontalOffset.pixels; 184 | for (int column = leadingColumn; column <= trailingColumn; column++) { 185 | double yLayoutOffset = (leadingRow * 200) - verticalOffset.pixels; 186 | for (int row = leadingRow; row <= trailingRow; row++) { 187 | final ChildVicinity vicinity = 188 | ChildVicinity(xIndex: column, yIndex: row); 189 | final RenderBox child = buildOrObtainChildFor(vicinity)!; 190 | child.layout(constraints.tighten(width: 200.0, height: 200.0)); 191 | 192 | parentDataOf(child).layoutOffset = Offset(xLayoutOffset, yLayoutOffset); 193 | yLayoutOffset += 200; 194 | } 195 | xLayoutOffset += 200; 196 | } 197 | 198 | final double verticalExtent = 200 * (maxRowIndex + 1); 199 | verticalOffset.applyContentDimensions( 200 | 0.0, 201 | clampDouble( 202 | verticalExtent - viewportDimension.height, 0.0, double.infinity), 203 | ); 204 | final double horizontalExtent = 200 * (maxColumnIndex + 1); 205 | horizontalOffset.applyContentDimensions( 206 | 0.0, 207 | clampDouble( 208 | horizontalExtent - viewportDimension.width, 0.0, double.infinity), 209 | ); 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /lib/14_ultra_gradients.dart: -------------------------------------------------------------------------------- 1 | // YT: https://www.youtube.com/@MaxonFlutter/ 2 | // Courses: https://www.atomsbox.com/ 3 | // Ultra Gradient example based on: https://medium.com/flutter-community/creating-ultra-gradients-with-flutter-d4e87003358e 4 | 5 | import 'dart:ui'; 6 | 7 | import 'package:flutter/material.dart'; 8 | 9 | void main() { 10 | runApp(const MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | const MyApp({super.key}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | debugShowCheckedModeBanner: false, 20 | theme: ThemeData.light(useMaterial3: true), 21 | home: const CounterWithUltraGradients(), 22 | ); 23 | } 24 | } 25 | 26 | class CounterWithUltraGradients extends StatefulWidget { 27 | const CounterWithUltraGradients({super.key}); 28 | 29 | @override 30 | State createState() => 31 | _CounterWithUltraGradientsState(); 32 | } 33 | 34 | class _CounterWithUltraGradientsState extends State { 35 | int _counter = 0; 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return BackgroundShapes( 40 | child: Scaffold( 41 | backgroundColor: Colors.transparent, 42 | body: Center( 43 | child: Padding( 44 | padding: const EdgeInsets.all(32.0), 45 | child: Column( 46 | mainAxisAlignment: MainAxisAlignment.center, 47 | children: [ 48 | Text( 49 | 'You have pushed the button this many times:', 50 | textAlign: TextAlign.center, 51 | style: Theme.of(context).textTheme.titleLarge, 52 | ), 53 | const SizedBox(height: 16.0), 54 | Text( 55 | '$_counter', 56 | style: Theme.of(context).textTheme.headlineMedium, 57 | ), 58 | ], 59 | ), 60 | ), 61 | ), 62 | floatingActionButton: FloatingActionButton( 63 | backgroundColor: Colors.orange, 64 | onPressed: () { 65 | setState(() { 66 | _counter++; 67 | }); 68 | }, 69 | child: const Icon(Icons.add), 70 | ), 71 | ), 72 | ); 73 | } 74 | } 75 | 76 | class BackgroundShapes extends StatefulWidget { 77 | const BackgroundShapes({ 78 | super.key, 79 | required this.child, 80 | }); 81 | 82 | final Widget child; 83 | 84 | @override 85 | State createState() => _BackgroundShapesState(); 86 | } 87 | 88 | class _BackgroundShapesState extends State 89 | with SingleTickerProviderStateMixin { 90 | @override 91 | void initState() { 92 | _controller = AnimationController( 93 | vsync: this, 94 | duration: const Duration(seconds: 10), 95 | ); 96 | _animation = Tween( 97 | begin: 0, 98 | end: 1, 99 | ).animate(_controller); 100 | _controller.repeat(reverse: true); 101 | super.initState(); 102 | } 103 | 104 | late AnimationController _controller; 105 | late Animation _animation; 106 | 107 | @override 108 | Widget build(BuildContext context) { 109 | return Material( 110 | child: Stack( 111 | children: [ 112 | AnimatedBuilder( 113 | animation: _animation, 114 | builder: (context, child) { 115 | return CustomPaint( 116 | painter: BackgroundPainter(_animation), 117 | child: Container(), 118 | ); 119 | }, 120 | ), 121 | BackdropFilter( 122 | filter: ImageFilter.blur(sigmaX: 60, sigmaY: 60), 123 | child: Container( 124 | color: Colors.black.withOpacity(0.1), 125 | ), 126 | ), 127 | widget.child, 128 | ], 129 | ), 130 | ); 131 | } 132 | 133 | @override 134 | void dispose() { 135 | _controller.removeStatusListener((status) {}); 136 | _controller.dispose(); 137 | super.dispose(); 138 | } 139 | } 140 | 141 | class BackgroundPainter extends CustomPainter { 142 | final Animation animation; 143 | 144 | const BackgroundPainter(this.animation); 145 | 146 | Offset getOffset(Path path) { 147 | final pms = path.computeMetrics(forceClosed: false).elementAt(0); 148 | final length = pms.length; 149 | final offset = pms.getTangentForOffset(length * animation.value)!.position; 150 | return offset; 151 | } 152 | 153 | @override 154 | void paint(Canvas canvas, Size size) { 155 | final paint = Paint(); 156 | paint.maskFilter = const MaskFilter.blur( 157 | BlurStyle.normal, 158 | 30, 159 | ); 160 | drawShape1(canvas, size, paint, Colors.orange); 161 | drawShape2(canvas, size, paint, Colors.purple); 162 | drawShape3(canvas, size, paint, Colors.blue); 163 | } 164 | 165 | @override 166 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 167 | return oldDelegate != this; 168 | } 169 | 170 | void drawShape1( 171 | Canvas canvas, 172 | Size size, 173 | Paint paint, 174 | Color color, 175 | ) { 176 | paint.color = color; 177 | Path path = Path(); 178 | 179 | path.moveTo(size.width, 0); 180 | path.quadraticBezierTo( 181 | size.width / 2, 182 | size.height / 2, 183 | -100, 184 | size.height / 4, 185 | ); 186 | 187 | final offset = getOffset(path); 188 | canvas.drawCircle(offset, 150, paint); 189 | } 190 | 191 | void drawShape2( 192 | Canvas canvas, 193 | Size size, 194 | Paint paint, 195 | Color color, 196 | ) { 197 | paint.color = color; 198 | Path path = Path(); 199 | 200 | path.moveTo(size.width, size.height); 201 | path.quadraticBezierTo( 202 | size.width / 2, 203 | size.height / 2, 204 | size.width * 0.9, 205 | size.height * 0.9, 206 | ); 207 | 208 | final offset = getOffset(path); 209 | canvas.drawCircle(offset, 250, paint); 210 | } 211 | 212 | void drawShape3( 213 | Canvas canvas, 214 | Size size, 215 | Paint paint, 216 | Color color, 217 | ) { 218 | paint.color = color; 219 | Path path = Path(); 220 | 221 | path.moveTo(0, 0); 222 | path.quadraticBezierTo( 223 | 0, 224 | size.height, 225 | size.width / 3, 226 | size.height / 3, 227 | ); 228 | 229 | final offset = getOffset(path); 230 | canvas.drawCircle(offset, 250, paint); 231 | } 232 | } 233 | 234 | // @override 235 | // Widget build(BuildContext context) { 236 | // return BackgroundShapes( 237 | // child: Scaffold( 238 | // backgroundColor: Colors.transparent, 239 | // body: Center( 240 | // child: Padding( 241 | // padding: const EdgeInsets.all(32.0), 242 | // child: ... 243 | // ), 244 | // ), 245 | // ), 246 | // ); 247 | // } 248 | 249 | // class BackgroundPainter extends CustomPainter { 250 | // @override 251 | // void paint(Canvas canvas, Size size) { 252 | // final paint = Paint(); 253 | // paint.maskFilter = const MaskFilter.blur( 254 | // BlurStyle.normal, 255 | // 30, 256 | // ); 257 | // drawShape1(canvas, size, paint, Colors.orange); 258 | // drawShape2(canvas, size, paint, Colors.purple); 259 | // drawShape3(canvas, size, paint, Colors.blue); 260 | // } 261 | 262 | // void drawShape1() { 263 | // ... 264 | // } 265 | // } 266 | 267 | // class _BackgroundShapesState extends State 268 | // with SingleTickerProviderStateMixin { 269 | // @override 270 | // void initState() { 271 | // ... 272 | // super.initState(); 273 | // } 274 | 275 | // late AnimationController _controller; 276 | // late Animation _animation; 277 | 278 | // @override 279 | // Widget build(BuildContext context) { 280 | // return AnimatedBuilder( 281 | // animation: _animation, 282 | // builder: (context, child) { 283 | // return ... 284 | // }, 285 | // ); 286 | // } 287 | // } 288 | 289 | -------------------------------------------------------------------------------- /lib/15_digital_signature.dart: -------------------------------------------------------------------------------- 1 | // Digital signature 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'dart:typed_data'; 5 | 6 | import 'package:flutter/material.dart'; 7 | import 'package:signature/signature.dart'; 8 | 9 | void main() { 10 | runApp(const MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | const MyApp({super.key}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | debugShowCheckedModeBanner: false, 20 | theme: ThemeData.light(useMaterial3: true), 21 | home: const DigitaSignatureExample(), 22 | ); 23 | } 24 | } 25 | 26 | class DigitaSignatureExample extends StatefulWidget { 27 | const DigitaSignatureExample({super.key}); 28 | 29 | @override 30 | State createState() => _DigitaSignatureExampleState(); 31 | } 32 | 33 | class _DigitaSignatureExampleState extends State { 34 | final SignatureController _controller = SignatureController( 35 | penStrokeWidth: 1, 36 | penColor: Colors.black, 37 | exportBackgroundColor: Colors.transparent, 38 | exportPenColor: Colors.black, 39 | onDrawStart: () => print('onDrawStart called!'), 40 | onDrawEnd: () => print('onDrawEnd called!'), 41 | ); 42 | 43 | @override 44 | void dispose() { 45 | _controller.dispose(); 46 | super.dispose(); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Scaffold( 52 | appBar: AppBar( 53 | title: const Text('Signature Demo'), 54 | actions: [ 55 | IconButton( 56 | onPressed: () { 57 | setState(() => _controller.undo()); 58 | }, 59 | icon: const Icon(Icons.undo), 60 | ), 61 | const SizedBox(width: 8.0), 62 | IconButton( 63 | onPressed: () { 64 | setState(() => _controller.redo()); 65 | }, 66 | icon: const Icon(Icons.redo), 67 | ), 68 | const SizedBox(width: 8.0), 69 | ], 70 | ), 71 | body: Column( 72 | children: [ 73 | Signature( 74 | controller: _controller, 75 | height: 300, 76 | backgroundColor: Theme.of(context).colorScheme.primaryContainer, 77 | ), 78 | Padding( 79 | padding: const EdgeInsets.all(16.0), 80 | child: Column( 81 | children: [ 82 | FilledButton.icon( 83 | style: FilledButton.styleFrom( 84 | minimumSize: const Size.fromHeight(48.0), 85 | ), 86 | onPressed: () async { 87 | final Uint8List? data = await _controller.toPngBytes( 88 | height: 1000, 89 | width: 1000, 90 | ); 91 | 92 | print(data); 93 | }, 94 | icon: const Icon(Icons.image), 95 | label: const Text('Export Image'), 96 | ), 97 | const SizedBox(height: 8.0), 98 | FilledButton.icon( 99 | style: FilledButton.styleFrom( 100 | minimumSize: const Size.fromHeight(48.0), 101 | ), 102 | onPressed: () { 103 | setState(() => _controller.clear()); 104 | }, 105 | icon: const Icon(Icons.clear), 106 | label: Text('Clear'), 107 | ), 108 | ], 109 | ), 110 | ) 111 | ], 112 | ), 113 | ); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/16_sparkline_chart.dart: -------------------------------------------------------------------------------- 1 | // Sparkline Chart with syncfusion_flutter_charts package 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:syncfusion_flutter_charts/sparkcharts.dart'; 7 | 8 | void main() { 9 | runApp(const MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | debugShowCheckedModeBanner: false, 19 | theme: ThemeData.light(useMaterial3: true), 20 | home: const SparklineExample(), 21 | ); 22 | } 23 | } 24 | 25 | class SparklineExample extends StatelessWidget { 26 | const SparklineExample({super.key}); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | centerTitle: false, 33 | title: const Text('Data Analytics with Flutter'), 34 | actions: [ 35 | IconButton( 36 | onPressed: () {}, 37 | icon: const Icon(Icons.search), 38 | ), 39 | ], 40 | ), 41 | body: SizedBox( 42 | height: 160, 43 | child: ListView( 44 | padding: const EdgeInsets.symmetric(horizontal: 8.0), 45 | scrollDirection: Axis.horizontal, 46 | children: [ 47 | Card( 48 | color: const Color(0xFF909CDF), 49 | child: Container( 50 | width: 285, 51 | height: 160, 52 | padding: const EdgeInsets.all(16.0), 53 | child: Column( 54 | children: [ 55 | Row( 56 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 57 | children: [ 58 | Text( 59 | 'Users:', 60 | style: Theme.of(context) 61 | .textTheme 62 | .headlineSmall! 63 | .copyWith( 64 | color: Colors.white, 65 | fontWeight: FontWeight.bold, 66 | ), 67 | ), 68 | Text( 69 | '200', 70 | style: Theme.of(context) 71 | .textTheme 72 | .headlineLarge! 73 | .copyWith( 74 | color: Colors.white, 75 | fontWeight: FontWeight.bold, 76 | ), 77 | ), 78 | ], 79 | ), 80 | SizedBox(height: 8.0), 81 | Expanded(child: SparklineChart()), 82 | ], 83 | ), 84 | ), 85 | ), 86 | Card( 87 | color: const Color(0xFF9C254D), 88 | child: Container( 89 | width: 285, 90 | height: 160, 91 | padding: const EdgeInsets.all(16.0), 92 | child: Column( 93 | children: [ 94 | Row( 95 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 96 | children: [ 97 | Text( 98 | '# of Users:', 99 | style: Theme.of(context) 100 | .textTheme 101 | .headlineSmall! 102 | .copyWith( 103 | color: Colors.white, 104 | fontWeight: FontWeight.bold, 105 | ), 106 | ), 107 | Text( 108 | '134', 109 | style: Theme.of(context) 110 | .textTheme 111 | .headlineLarge! 112 | .copyWith( 113 | color: Colors.white, 114 | fontWeight: FontWeight.bold, 115 | ), 116 | ), 117 | ], 118 | ), 119 | SizedBox(height: 8.0), 120 | Expanded(child: SparkareaChart()), 121 | ], 122 | ), 123 | ), 124 | ), 125 | Card( 126 | color: const Color(0xFF131313), 127 | child: Container( 128 | width: 285, 129 | height: 160, 130 | padding: const EdgeInsets.all(16.0), 131 | child: Column( 132 | children: [ 133 | Row( 134 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 135 | children: [ 136 | Text( 137 | '# of Orders:', 138 | style: Theme.of(context) 139 | .textTheme 140 | .headlineSmall! 141 | .copyWith( 142 | color: Colors.white, 143 | fontWeight: FontWeight.bold, 144 | ), 145 | ), 146 | Text( 147 | '59', 148 | style: Theme.of(context) 149 | .textTheme 150 | .headlineLarge! 151 | .copyWith( 152 | color: Colors.white, 153 | fontWeight: FontWeight.bold, 154 | ), 155 | ), 156 | ], 157 | ), 158 | SizedBox(height: 8.0), 159 | Expanded(child: SparkbarChart()), 160 | ], 161 | ), 162 | ), 163 | ), 164 | ], 165 | ), 166 | ), 167 | ); 168 | } 169 | } 170 | 171 | class SparklineChart extends StatelessWidget { 172 | const SparklineChart({super.key}); 173 | 174 | @override 175 | Widget build(BuildContext context) { 176 | return SfSparkLineChart( 177 | width: 1, 178 | axisLineWidth: 0, 179 | color: Colors.white, 180 | data: const [100, 60, 80, 50, 110, 50, 60], 181 | labelDisplayMode: SparkChartLabelDisplayMode.none, 182 | marker: const SparkChartMarker( 183 | shape: SparkChartMarkerShape.circle, 184 | borderColor: Colors.white, 185 | color: Colors.white, 186 | displayMode: SparkChartMarkerDisplayMode.all, 187 | ), 188 | trackball: SparkChartTrackball( 189 | activationMode: SparkChartActivationMode.tap, 190 | color: Theme.of(context).colorScheme.inverseSurface, 191 | borderWidth: 1, 192 | ), 193 | ); 194 | } 195 | } 196 | 197 | // class SparklineChart extends StatelessWidget { 198 | // const SparklineChart({super.key}); 199 | 200 | // @override 201 | // Widget build(BuildContext context) { 202 | // return SfSparkLineChart( 203 | // width: 1, 204 | // axisLineWidth: 0, 205 | // color: Colors.white, 206 | // data: const [100, 60, 80, 50, 110, 50, 60], 207 | // labelDisplayMode: SparkChartLabelDisplayMode.none, 208 | // marker: const SparkChartMarker( 209 | // shape: SparkChartMarkerShape.circle, 210 | // borderColor: Colors.white, 211 | // color: Colors.white, 212 | // displayMode: SparkChartMarkerDisplayMode.all, 213 | // ), 214 | // trackball: SparkChartTrackball( 215 | // activationMode: SparkChartActivationMode.tap, 216 | // color: Theme.of(context).colorScheme.inverseSurface, 217 | // borderWidth: 1, 218 | // ), 219 | // ); 220 | // } 221 | // } 222 | 223 | class SparkbarChart extends StatelessWidget { 224 | const SparkbarChart({super.key}); 225 | 226 | @override 227 | Widget build(BuildContext context) { 228 | return SfSparkBarChart( 229 | axisLineWidth: 0, 230 | color: Colors.white, 231 | data: const [100, 60, 80, 50, 110, 50, 60], 232 | labelDisplayMode: SparkChartLabelDisplayMode.all, 233 | trackball: SparkChartTrackball( 234 | activationMode: SparkChartActivationMode.tap, 235 | color: Theme.of(context).colorScheme.inverseSurface, 236 | borderWidth: 1, 237 | ), 238 | ); 239 | } 240 | } 241 | 242 | class SparkareaChart extends StatelessWidget { 243 | const SparkareaChart({super.key}); 244 | 245 | @override 246 | Widget build(BuildContext context) { 247 | return SfSparkAreaChart( 248 | axisLineWidth: 0, 249 | color: Colors.white, 250 | data: const [100, 60, 80, 50, 110, 50, 60], 251 | labelDisplayMode: SparkChartLabelDisplayMode.none, 252 | marker: const SparkChartMarker( 253 | shape: SparkChartMarkerShape.circle, 254 | borderWidth: 0.0, 255 | color: Colors.white, 256 | displayMode: SparkChartMarkerDisplayMode.all, 257 | ), 258 | trackball: SparkChartTrackball( 259 | activationMode: SparkChartActivationMode.tap, 260 | color: Theme.of(context).colorScheme.inverseSurface, 261 | borderWidth: 1, 262 | ), 263 | ); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /lib/17_funnel_chart.dart: -------------------------------------------------------------------------------- 1 | // Funnel Chart with syncfusion_flutter_charts package 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:syncfusion_flutter_charts/charts.dart'; 6 | 7 | void main() { 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | debugShowCheckedModeBanner: false, 18 | theme: ThemeData.light(useMaterial3: true), 19 | home: const FunnelExample(), 20 | ); 21 | } 22 | } 23 | 24 | class FunnelExample extends StatelessWidget { 25 | const FunnelExample({super.key}); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | appBar: AppBar( 31 | centerTitle: false, 32 | title: const Text('Analytics with Flutter'), 33 | actions: [ 34 | IconButton( 35 | onPressed: () {}, 36 | icon: const Icon(Icons.tune), 37 | ), 38 | IconButton( 39 | onPressed: () {}, 40 | icon: const Icon(Icons.search), 41 | ), 42 | ], 43 | ), 44 | body: Padding( 45 | padding: const EdgeInsets.all(8.0), 46 | child: Column( 47 | children: [ 48 | Card( 49 | child: Container( 50 | padding: const EdgeInsets.all(16.0), 51 | child: FunnelChart(), 52 | ), 53 | ) 54 | ], 55 | ), 56 | ), 57 | ); 58 | } 59 | } 60 | 61 | class FunnelChart extends StatefulWidget { 62 | const FunnelChart({super.key}); 63 | 64 | @override 65 | State createState() => _FunnelChartState(); 66 | } 67 | 68 | class _FunnelChartState extends State { 69 | var chartData = [ 70 | ChartData(1, 'Sessions', 200), 71 | ChartData(2, 'Add to Cart', 40), 72 | ChartData(3, 'Checkout Start', 24), 73 | ChartData(4, 'Purchase Completed', 12), 74 | ]; 75 | 76 | @override 77 | void initState() { 78 | chartData.sort((a, b) => a.index.compareTo(b.index)); 79 | chartData = chartData.reversed.toList(); 80 | super.initState(); 81 | } 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | return SfFunnelChart( 86 | legend: Legend( 87 | isVisible: true, 88 | overflowMode: LegendItemOverflowMode.scroll, 89 | position: LegendPosition.bottom, 90 | textStyle: Theme.of(context).textTheme.bodySmall, 91 | ), 92 | palette: const [ 93 | Color(0xFFFFF7BF), 94 | Color(0xFF5AAB84), 95 | Color(0xFF909CDF), 96 | Color(0xFF9C254D), 97 | ], 98 | series: FunnelSeries( 99 | dataSource: chartData, 100 | gapRatio: 0.1, 101 | dataLabelSettings: const DataLabelSettings( 102 | isVisible: true, 103 | labelPosition: ChartDataLabelPosition.outside, 104 | useSeriesColor: true, 105 | ), 106 | emptyPointSettings: 107 | const EmptyPointSettings(mode: EmptyPointMode.average), 108 | xValueMapper: (ChartData data, _) => data.x, 109 | yValueMapper: (ChartData data, _) => data.y, 110 | ), 111 | ); 112 | } 113 | } 114 | 115 | class ChartData { 116 | ChartData(this.index, this.x, this.y, [this.color]); 117 | final int index; 118 | final String x; 119 | final double y; 120 | final Color? color; 121 | } 122 | -------------------------------------------------------------------------------- /lib/18_radial_bar_chart.dart: -------------------------------------------------------------------------------- 1 | // Radial Bar Chart with syncfusion_flutter_charts package 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | import 'package:flutter/material.dart'; 5 | import 'package:syncfusion_flutter_charts/charts.dart'; 6 | 7 | void main() { 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | debugShowCheckedModeBanner: false, 18 | theme: ThemeData.light(useMaterial3: true), 19 | home: const RadialBarExample(), 20 | ); 21 | } 22 | } 23 | 24 | class RadialBarExample extends StatelessWidget { 25 | const RadialBarExample({super.key}); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | appBar: AppBar( 31 | centerTitle: false, 32 | title: const Text('Analytics with Flutter'), 33 | actions: [ 34 | IconButton( 35 | onPressed: () {}, 36 | icon: const Icon(Icons.tune), 37 | ), 38 | IconButton( 39 | onPressed: () {}, 40 | icon: const Icon(Icons.search), 41 | ), 42 | ], 43 | ), 44 | body: Padding( 45 | padding: const EdgeInsets.all(8.0), 46 | child: Column( 47 | children: [ 48 | Card( 49 | child: Container( 50 | padding: const EdgeInsets.all(16.0), 51 | child: const RadialBarChart(), 52 | ), 53 | ), 54 | Card( 55 | child: Container( 56 | padding: const EdgeInsets.all(16.0), 57 | child: const RadialBarChartV2(), 58 | ), 59 | ) 60 | ], 61 | ), 62 | ), 63 | ); 64 | } 65 | } 66 | 67 | class RadialBarChart extends StatelessWidget { 68 | const RadialBarChart({super.key}); 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | final List chartData = [ 73 | ChartData('Target', 80, const Color(0xFF909CDF)), 74 | ChartData('Actuals', 50, const Color(0xFF9C254D)), 75 | ]; 76 | 77 | return SfCircularChart( 78 | legend: const Legend( 79 | isVisible: true, 80 | position: LegendPosition.bottom, 81 | ), 82 | series: >[ 83 | RadialBarSeries( 84 | useSeriesColor: true, 85 | trackOpacity: 0.3, 86 | cornerStyle: CornerStyle.bothCurve, 87 | dataSource: chartData, 88 | maximumValue: 100, 89 | trackBorderWidth: 2, 90 | radius: '100%', 91 | trackBorderColor: Colors.white, 92 | pointColorMapper: (ChartData data, _) => data.color, 93 | xValueMapper: (ChartData sales, _) => sales.x, 94 | yValueMapper: (ChartData sales, _) => sales.y, 95 | dataLabelSettings: DataLabelSettings( 96 | isVisible: true, 97 | textStyle: Theme.of(context) 98 | .textTheme 99 | .labelMedium! 100 | .copyWith(fontWeight: FontWeight.bold), 101 | ), 102 | ) 103 | ], 104 | ); 105 | } 106 | } 107 | 108 | class RadialBarChartV2 extends StatelessWidget { 109 | const RadialBarChartV2({super.key}); 110 | 111 | @override 112 | Widget build(BuildContext context) { 113 | final List chartData = [ 114 | ChartData('Low', 3500, const Color(0xFF1313131)), 115 | ChartData('Average', 7200, const Color(0xFF909CDF)), 116 | ChartData('High', 10500, const Color(0xFF9C254D)), 117 | ]; 118 | return SfCircularChart( 119 | legend: const Legend( 120 | isVisible: true, 121 | position: LegendPosition.bottom, 122 | ), 123 | series: >[ 124 | RadialBarSeries( 125 | maximumValue: 6000, 126 | radius: '100%', 127 | gap: '3%', 128 | dataSource: chartData, 129 | xValueMapper: (ChartData data, _) => data.x, 130 | yValueMapper: (ChartData data, _) => data.y, 131 | pointColorMapper: (ChartData data, _) => data.color) 132 | ], 133 | ); 134 | } 135 | } 136 | 137 | class ChartData { 138 | ChartData( 139 | this.x, 140 | this.y, 141 | this.color, 142 | ); 143 | final String x; 144 | final double y; 145 | final Color color; 146 | } 147 | -------------------------------------------------------------------------------- /lib/19_analytics_view.dart: -------------------------------------------------------------------------------- 1 | // Radial Bar Chart with syncfusion_flutter_charts package 2 | // YT: https://www.youtube.com/@MaxonFlutter/ 3 | // Courses: https://www.atomsbox.com/ 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_tips_and_examples/17_funnel_chart.dart'; 7 | 8 | import '16_sparkline_chart.dart'; 9 | import '18_radial_bar_chart.dart'; 10 | 11 | void main() { 12 | runApp(const MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | const MyApp({super.key}); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | debugShowCheckedModeBanner: false, 22 | theme: ThemeData.light(useMaterial3: true), 23 | home: const AnalyticsViewExample(), 24 | ); 25 | } 26 | } 27 | 28 | class AnalyticsViewExample extends StatelessWidget { 29 | const AnalyticsViewExample({super.key}); 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return Scaffold( 34 | appBar: AppBar( 35 | centerTitle: false, 36 | title: const Text(' Analytics with Flutter'), 37 | actions: [ 38 | IconButton( 39 | onPressed: () {}, 40 | icon: const Icon(Icons.tune), 41 | ), 42 | IconButton( 43 | onPressed: () {}, 44 | icon: const Icon(Icons.search), 45 | ), 46 | ], 47 | ), 48 | body: SingleChildScrollView( 49 | child: Padding( 50 | padding: const EdgeInsets.all(8.0), 51 | child: Column( 52 | children: [ 53 | SizedBox( 54 | height: 160, 55 | child: ListView( 56 | padding: EdgeInsets.zero, 57 | scrollDirection: Axis.horizontal, 58 | children: [ 59 | Card( 60 | color: const Color(0xFF909CDF), 61 | child: Container( 62 | width: 285, 63 | height: 160, 64 | padding: const EdgeInsets.all(16.0), 65 | child: Column( 66 | children: [ 67 | Row( 68 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 69 | children: [ 70 | Text( 71 | '# of Sessions:', 72 | style: Theme.of(context) 73 | .textTheme 74 | .headlineSmall! 75 | .copyWith( 76 | color: Colors.white, 77 | fontWeight: FontWeight.bold, 78 | ), 79 | ), 80 | Text( 81 | '200', 82 | style: Theme.of(context) 83 | .textTheme 84 | .headlineLarge! 85 | .copyWith( 86 | color: Colors.white, 87 | fontWeight: FontWeight.bold, 88 | ), 89 | ), 90 | ], 91 | ), 92 | SizedBox(height: 8.0), 93 | Expanded(child: SparklineChart()), 94 | ], 95 | ), 96 | ), 97 | ), 98 | Card( 99 | color: const Color(0xFF9C254D), 100 | child: Container( 101 | width: 285, 102 | height: 160, 103 | padding: const EdgeInsets.all(16.0), 104 | child: Column( 105 | children: [ 106 | Row( 107 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 108 | children: [ 109 | Text( 110 | '# of Users:', 111 | style: Theme.of(context) 112 | .textTheme 113 | .headlineSmall! 114 | .copyWith( 115 | color: Colors.white, 116 | fontWeight: FontWeight.bold, 117 | ), 118 | ), 119 | Text( 120 | '134', 121 | style: Theme.of(context) 122 | .textTheme 123 | .headlineLarge! 124 | .copyWith( 125 | color: Colors.white, 126 | fontWeight: FontWeight.bold, 127 | ), 128 | ), 129 | ], 130 | ), 131 | SizedBox(height: 8.0), 132 | Expanded(child: SparkareaChart()), 133 | ], 134 | ), 135 | ), 136 | ), 137 | Card( 138 | color: const Color(0xFF131313), 139 | child: Container( 140 | width: 285, 141 | height: 160, 142 | padding: const EdgeInsets.all(16.0), 143 | child: Column( 144 | children: [ 145 | Row( 146 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 147 | children: [ 148 | Text( 149 | '# of Orders:', 150 | style: Theme.of(context) 151 | .textTheme 152 | .headlineSmall! 153 | .copyWith( 154 | color: Colors.white, 155 | fontWeight: FontWeight.bold, 156 | ), 157 | ), 158 | Text( 159 | '59', 160 | style: Theme.of(context) 161 | .textTheme 162 | .headlineLarge! 163 | .copyWith( 164 | color: Colors.white, 165 | fontWeight: FontWeight.bold, 166 | ), 167 | ), 168 | ], 169 | ), 170 | SizedBox(height: 8.0), 171 | Expanded(child: SparkbarChart()), 172 | ], 173 | ), 174 | ), 175 | ), 176 | ], 177 | ), 178 | ), 179 | Card( 180 | child: Container( 181 | padding: const EdgeInsets.all(16.0), 182 | child: const RadialBarChartV2(), 183 | ), 184 | ), 185 | Card( 186 | child: Container( 187 | padding: const EdgeInsets.all(16.0), 188 | child: const FunnelChart(), 189 | ), 190 | ), 191 | ], 192 | ), 193 | ), 194 | ), 195 | ); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /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 | sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "3.3.7" 12 | args: 13 | dependency: transitive 14 | description: 15 | name: args 16 | sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.4.2" 20 | async: 21 | dependency: transitive 22 | description: 23 | name: async 24 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.11.0" 28 | boolean_selector: 29 | dependency: transitive 30 | description: 31 | name: boolean_selector 32 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.1.1" 36 | carousel_slider: 37 | dependency: "direct main" 38 | description: 39 | name: carousel_slider 40 | sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "4.2.1" 44 | characters: 45 | dependency: transitive 46 | description: 47 | name: characters 48 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.3.0" 52 | clock: 53 | dependency: transitive 54 | description: 55 | name: clock 56 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.1.1" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.18.0" 68 | convert: 69 | dependency: transitive 70 | description: 71 | name: convert 72 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "3.1.1" 76 | crypto: 77 | dependency: transitive 78 | description: 79 | name: crypto 80 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "3.0.3" 84 | cupertino_icons: 85 | dependency: "direct main" 86 | description: 87 | name: cupertino_icons 88 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "1.0.5" 92 | dots_indicator: 93 | dependency: "direct main" 94 | description: 95 | name: dots_indicator 96 | sha256: "58b6a365744aa62aa1b70c4ea29e5106fbe064f5edaf7e9652e9b856edbfd9bb" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "3.0.0" 100 | fake_async: 101 | dependency: transitive 102 | description: 103 | name: fake_async 104 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "1.3.1" 108 | flutter: 109 | dependency: "direct main" 110 | description: flutter 111 | source: sdk 112 | version: "0.0.0" 113 | flutter_animate: 114 | dependency: "direct main" 115 | description: 116 | name: flutter_animate 117 | sha256: be54662837a6e66cc53ee88549e808c625275e0faf5a43e11cf3182cb0bd1b02 118 | url: "https://pub.dev" 119 | source: hosted 120 | version: "4.2.0" 121 | flutter_lints: 122 | dependency: "direct dev" 123 | description: 124 | name: flutter_lints 125 | sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" 126 | url: "https://pub.dev" 127 | source: hosted 128 | version: "2.0.2" 129 | flutter_svg: 130 | dependency: transitive 131 | description: 132 | name: flutter_svg 133 | sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" 134 | url: "https://pub.dev" 135 | source: hosted 136 | version: "2.0.7" 137 | flutter_test: 138 | dependency: "direct dev" 139 | description: flutter 140 | source: sdk 141 | version: "0.0.0" 142 | flutter_web_plugins: 143 | dependency: transitive 144 | description: flutter 145 | source: sdk 146 | version: "0.0.0" 147 | http: 148 | dependency: "direct main" 149 | description: 150 | name: http 151 | sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" 152 | url: "https://pub.dev" 153 | source: hosted 154 | version: "1.1.0" 155 | http_parser: 156 | dependency: "direct main" 157 | description: 158 | name: http_parser 159 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 160 | url: "https://pub.dev" 161 | source: hosted 162 | version: "4.0.2" 163 | image: 164 | dependency: transitive 165 | description: 166 | name: image 167 | sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf 168 | url: "https://pub.dev" 169 | source: hosted 170 | version: "4.0.17" 171 | intl: 172 | dependency: transitive 173 | description: 174 | name: intl 175 | sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" 176 | url: "https://pub.dev" 177 | source: hosted 178 | version: "0.18.1" 179 | js: 180 | dependency: transitive 181 | description: 182 | name: js 183 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 184 | url: "https://pub.dev" 185 | source: hosted 186 | version: "0.6.7" 187 | lints: 188 | dependency: transitive 189 | description: 190 | name: lints 191 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 192 | url: "https://pub.dev" 193 | source: hosted 194 | version: "2.1.1" 195 | lottie: 196 | dependency: "direct main" 197 | description: 198 | name: lottie 199 | sha256: f461105d3a35887b27089abf9c292334478dd292f7b47ecdccb6ae5c37a22c80 200 | url: "https://pub.dev" 201 | source: hosted 202 | version: "2.4.0" 203 | matcher: 204 | dependency: transitive 205 | description: 206 | name: matcher 207 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" 208 | url: "https://pub.dev" 209 | source: hosted 210 | version: "0.12.16" 211 | material_color_utilities: 212 | dependency: transitive 213 | description: 214 | name: material_color_utilities 215 | sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" 216 | url: "https://pub.dev" 217 | source: hosted 218 | version: "0.5.0" 219 | meta: 220 | dependency: transitive 221 | description: 222 | name: meta 223 | sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e 224 | url: "https://pub.dev" 225 | source: hosted 226 | version: "1.10.0" 227 | path: 228 | dependency: transitive 229 | description: 230 | name: path 231 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 232 | url: "https://pub.dev" 233 | source: hosted 234 | version: "1.8.3" 235 | path_parsing: 236 | dependency: transitive 237 | description: 238 | name: path_parsing 239 | sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf 240 | url: "https://pub.dev" 241 | source: hosted 242 | version: "1.0.1" 243 | petitparser: 244 | dependency: transitive 245 | description: 246 | name: petitparser 247 | sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 248 | url: "https://pub.dev" 249 | source: hosted 250 | version: "5.4.0" 251 | plugin_platform_interface: 252 | dependency: transitive 253 | description: 254 | name: plugin_platform_interface 255 | sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" 256 | url: "https://pub.dev" 257 | source: hosted 258 | version: "2.1.5" 259 | pointycastle: 260 | dependency: transitive 261 | description: 262 | name: pointycastle 263 | sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" 264 | url: "https://pub.dev" 265 | source: hosted 266 | version: "3.7.3" 267 | popover: 268 | dependency: "direct main" 269 | description: 270 | name: popover 271 | sha256: "59f4a55ebb484d012c8aaa273ad58eee571945231b71fb938c5a69f63b5a94d4" 272 | url: "https://pub.dev" 273 | source: hosted 274 | version: "0.2.8+2" 275 | signature: 276 | dependency: "direct main" 277 | description: 278 | name: signature 279 | sha256: d95143b8e310b395ea0be59a46bb69fa24106cb6ec79815fc56fd320268e24e6 280 | url: "https://pub.dev" 281 | source: hosted 282 | version: "5.4.0" 283 | sky_engine: 284 | dependency: transitive 285 | description: flutter 286 | source: sdk 287 | version: "0.0.99" 288 | source_span: 289 | dependency: transitive 290 | description: 291 | name: source_span 292 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 293 | url: "https://pub.dev" 294 | source: hosted 295 | version: "1.10.0" 296 | stack_trace: 297 | dependency: transitive 298 | description: 299 | name: stack_trace 300 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 301 | url: "https://pub.dev" 302 | source: hosted 303 | version: "1.11.1" 304 | stream_channel: 305 | dependency: transitive 306 | description: 307 | name: stream_channel 308 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 309 | url: "https://pub.dev" 310 | source: hosted 311 | version: "2.1.2" 312 | string_scanner: 313 | dependency: transitive 314 | description: 315 | name: string_scanner 316 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 317 | url: "https://pub.dev" 318 | source: hosted 319 | version: "1.2.0" 320 | syncfusion_flutter_charts: 321 | dependency: "direct main" 322 | description: 323 | name: syncfusion_flutter_charts 324 | sha256: "6f2ea3eaa34b998ba68461f6c8457f01cf8c07cf376a57069f9995a9cae1eb33" 325 | url: "https://pub.dev" 326 | source: hosted 327 | version: "24.1.41" 328 | syncfusion_flutter_core: 329 | dependency: transitive 330 | description: 331 | name: syncfusion_flutter_core 332 | sha256: "69c827931957d5b121ee9f0b9b0b8d7d0d1ac537b61bcdd5c3fbffc044bbe86e" 333 | url: "https://pub.dev" 334 | source: hosted 335 | version: "24.1.41" 336 | term_glyph: 337 | dependency: transitive 338 | description: 339 | name: term_glyph 340 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 341 | url: "https://pub.dev" 342 | source: hosted 343 | version: "1.2.1" 344 | test_api: 345 | dependency: transitive 346 | description: 347 | name: test_api 348 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" 349 | url: "https://pub.dev" 350 | source: hosted 351 | version: "0.6.1" 352 | typed_data: 353 | dependency: transitive 354 | description: 355 | name: typed_data 356 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 357 | url: "https://pub.dev" 358 | source: hosted 359 | version: "1.3.2" 360 | url_launcher: 361 | dependency: "direct main" 362 | description: 363 | name: url_launcher 364 | sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e" 365 | url: "https://pub.dev" 366 | source: hosted 367 | version: "6.1.12" 368 | url_launcher_android: 369 | dependency: transitive 370 | description: 371 | name: url_launcher_android 372 | sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025" 373 | url: "https://pub.dev" 374 | source: hosted 375 | version: "6.0.38" 376 | url_launcher_ios: 377 | dependency: transitive 378 | description: 379 | name: url_launcher_ios 380 | sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" 381 | url: "https://pub.dev" 382 | source: hosted 383 | version: "6.1.4" 384 | url_launcher_linux: 385 | dependency: transitive 386 | description: 387 | name: url_launcher_linux 388 | sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" 389 | url: "https://pub.dev" 390 | source: hosted 391 | version: "3.0.5" 392 | url_launcher_macos: 393 | dependency: transitive 394 | description: 395 | name: url_launcher_macos 396 | sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1" 397 | url: "https://pub.dev" 398 | source: hosted 399 | version: "3.0.6" 400 | url_launcher_platform_interface: 401 | dependency: transitive 402 | description: 403 | name: url_launcher_platform_interface 404 | sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea 405 | url: "https://pub.dev" 406 | source: hosted 407 | version: "2.1.3" 408 | url_launcher_web: 409 | dependency: transitive 410 | description: 411 | name: url_launcher_web 412 | sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4 413 | url: "https://pub.dev" 414 | source: hosted 415 | version: "2.0.18" 416 | url_launcher_windows: 417 | dependency: transitive 418 | description: 419 | name: url_launcher_windows 420 | sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422" 421 | url: "https://pub.dev" 422 | source: hosted 423 | version: "3.0.7" 424 | vector_graphics: 425 | dependency: transitive 426 | description: 427 | name: vector_graphics 428 | sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" 429 | url: "https://pub.dev" 430 | source: hosted 431 | version: "1.1.7" 432 | vector_graphics_codec: 433 | dependency: transitive 434 | description: 435 | name: vector_graphics_codec 436 | sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" 437 | url: "https://pub.dev" 438 | source: hosted 439 | version: "1.1.7" 440 | vector_graphics_compiler: 441 | dependency: transitive 442 | description: 443 | name: vector_graphics_compiler 444 | sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" 445 | url: "https://pub.dev" 446 | source: hosted 447 | version: "1.1.7" 448 | vector_math: 449 | dependency: transitive 450 | description: 451 | name: vector_math 452 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 453 | url: "https://pub.dev" 454 | source: hosted 455 | version: "2.1.4" 456 | web: 457 | dependency: transitive 458 | description: 459 | name: web 460 | sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 461 | url: "https://pub.dev" 462 | source: hosted 463 | version: "0.3.0" 464 | xml: 465 | dependency: transitive 466 | description: 467 | name: xml 468 | sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" 469 | url: "https://pub.dev" 470 | source: hosted 471 | version: "6.3.0" 472 | sdks: 473 | dart: ">=3.2.0-194.0.dev <4.0.0" 474 | flutter: ">=3.10.0" 475 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_tips_and_examples 2 | description: A new Flutter project. 3 | publish_to: 'none' 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: '>=3.0.0 <4.0.0' 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | cupertino_icons: ^1.0.2 13 | lottie: ^2.4.0 14 | flutter_animate: ^4.2.0 15 | http: ^1.1.0 16 | http_parser: ^4.0.2 17 | carousel_slider: ^4.2.1 18 | dots_indicator: ^3.0.0 19 | popover: ^0.2.8+2 20 | url_launcher: ^6.1.12 21 | signature: ^5.4.0 22 | syncfusion_flutter_charts: ^24.1.41 23 | 24 | dev_dependencies: 25 | flutter_test: 26 | sdk: flutter 27 | flutter_lints: ^2.0.0 28 | 29 | 30 | flutter: 31 | uses-material-design: true 32 | 33 | assets: 34 | - assets/ 35 | - assets/images/ 36 | - assets/videos/ 37 | - assets/audios/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxonflutter/Flutter-Tips-And-Examples/89b9059eb12a6428def85e990c59d724375da2e2/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_tips_and_examples 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_tips_and_examples", 3 | "short_name": "flutter_tips_and_examples", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | --------------------------------------------------------------------------------