├── .gitignore ├── Cover image.png ├── LICENSE ├── README.md ├── chapter_01 ├── dummy_project │ ├── .gitignore │ ├── app │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── myapplication │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── myapplication │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── drawable │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── myapplication │ │ │ └── ExampleUnitTest.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── hello_flutter │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── android │ │ ├── app │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── hello_flutter │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res │ │ │ │ │ ├── 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 │ │ │ │ │ └── styles.xml │ │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ └── settings.gradle │ ├── ios │ │ ├── Flutter │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ └── Release.xcconfig │ │ ├── Runner.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ └── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── Runner │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── 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 │ │ │ └── main.m │ ├── lib │ │ └── main.dart │ ├── pubspec.lock │ └── pubspec.yaml └── hello_modern_languages │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── hello_modern_languages │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── 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 │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle │ ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── 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 │ ├── lib │ └── main.dart │ ├── pubspec.lock │ ├── pubspec.yaml │ └── test │ └── widget_test.dart ├── chapter_02 ├── .gitignore ├── 02_introduction_to_dart.iml ├── CHANGELOG.md ├── README.md ├── analysis_options.yaml ├── bin │ └── main.dart ├── lib │ ├── 01-declaring_variables.dart │ ├── 02-strings.dart │ ├── 03-functions.dart │ ├── 04-classes.dart │ ├── 05-generics.dart │ ├── 06-collections.dart │ ├── 07-higher-order-functions.dart │ ├── 08-cascade.dart │ └── Builder.dart └── pubspec.yaml ├── chapter_03 ├── .gitignore ├── .metadata ├── README.md ├── assets │ ├── LeckerliOne-Regular.ttf │ ├── beach.jpg │ ├── dog.jpg │ ├── textiles.jpg │ └── woman_shopping.jpg ├── lib │ ├── basic_screen.dart │ ├── immutable_widget.dart │ ├── main.dart │ └── text_layout.dart ├── pubspec.lock └── pubspec.yaml ├── chapter_04 ├── .gitignore ├── .metadata ├── README.md ├── lib │ ├── deep_tree.dart │ ├── e_commerce_screen_after.dart │ ├── e_commerce_screen_before.dart │ ├── flex_screen.dart │ ├── profile_screen.dart │ └── star.dart ├── pubspec.lock └── pubspec.yaml ├── chapter_05 ├── .gitignore ├── .metadata ├── README.md ├── lib │ ├── login_screen.dart │ ├── main.dart │ ├── platform_alert.dart │ └── stopwatch.dart ├── pubspec.lock └── pubspec.yaml ├── chapter_06 ├── lib │ ├── controllers │ │ └── plan_controller.dart │ ├── main.dart │ ├── models │ │ ├── data_layer.dart │ │ ├── plan.dart │ │ └── task.dart │ ├── plan_provider.dart │ ├── repositories │ │ ├── in_memory_cache.dart │ │ └── repository.dart │ ├── services │ │ └── plan_services.dart │ └── views │ │ ├── plan_creator_screen.dart │ │ └── plan_screen.dart └── pubspec.yaml ├── chapter_07 ├── lib │ ├── generated_plugin_registrant.dart │ ├── location_screen.dart │ ├── main.dart │ ├── navigation_dialog.dart │ ├── navigation_first.dart │ └── navigation_second.dart └── pubspec.yaml ├── chapter_08 ├── assets │ └── pizzalist.json ├── lib │ ├── generated_plugin_registrant.dart │ ├── httphelper.dart │ ├── main.dart │ ├── pizza.dart │ └── pizza_detail.dart └── pubspec.yaml ├── chapter_09 ├── chapter_9_a │ ├── lib │ │ ├── main.dart │ │ └── stream.dart │ └── pubspec.yaml └── chapter_9_b │ ├── lib │ ├── countdown_bloc.dart │ ├── main.dart │ └── stream.dart │ └── pubspec.yaml ├── chapter_10 ├── lib │ └── main.dart └── pubspec.yaml ├── chapter_11 ├── lib │ ├── animatedlist.dart │ ├── detail_screen.dart │ ├── dismissible.dart │ ├── fade_transition.dart │ ├── list_screen.dart │ ├── main.dart │ ├── my_animation.dart │ └── shape_animation.dart └── pubspec.yaml ├── chapter_12 ├── lib │ ├── generated_plugin_registrant.dart │ ├── happy_screen.dart │ ├── login_screen.dart │ ├── main.dart │ ├── shared │ │ └── firebase_authentication.dart │ └── upload_file.dart └── pubspec.yaml ├── chapter_13 ├── lib │ ├── camera.dart │ ├── generated_plugin_registrant.dart │ ├── language.dart │ ├── main.dart │ ├── ml.dart │ ├── picture.dart │ └── result.dart └── pubspec.yaml └── chapter_15 ├── lib ├── .DS_Store ├── data │ └── http_helper.dart ├── main.dart ├── models │ └── book.dart └── screens │ └── book_list_screen.dart └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/.gitignore -------------------------------------------------------------------------------- /Cover image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/Cover image.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "29.0.0" 6 | defaultConfig { 7 | applicationId "com.example.myapplication" 8 | minSdkVersion 15 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation 'com.android.support:appcompat-v7:28.0.0' 25 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 26 | testImplementation 'junit:junit:4.12' 27 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 29 | } 30 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.myapplication; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.myapplication", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/java/com/example/myapplication/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.myapplication; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | public class MainActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_main); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | My Application 3 | 4 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/app/src/test/java/com/example/myapplication/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.myapplication; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /chapter_01/dummy_project/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.4.1' 11 | 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | jcenter() 21 | 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | 16 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/dummy_project/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /chapter_01/dummy_project/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Jun 22 20:54:41 EDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /chapter_01/dummy_project/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/README.md: -------------------------------------------------------------------------------- 1 | # hello_flutter 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.hello_flutter" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/java/com/example/hello_flutter/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.hello_flutter; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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. -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/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 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | hello_flutter 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chapter_01/hello_flutter/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hello_flutter 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://www.dartlang.org/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/README.md: -------------------------------------------------------------------------------- 1 | # hello_modern_languages 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.hello_modern_languages" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 67 | } 68 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/kotlin/com/example/hello_modern_languages/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.hello_modern_languages 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.71' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_01/hello_modern_languages/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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. -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/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 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | hello_modern_languages 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hello_modern_languages 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://www.dartlang.org/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /chapter_01/hello_modern_languages/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:hello_modern_languages/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /chapter_02/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs 8 | build/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | -------------------------------------------------------------------------------- /chapter_02/02_introduction_to_dart.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter_02/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version, created by Stagehand 4 | -------------------------------------------------------------------------------- /chapter_02/README.md: -------------------------------------------------------------------------------- 1 | A sample command-line application. 2 | 3 | Created from templates made available by Stagehand under a BSD-style 4 | [license](https://github.com/dart-lang/stagehand/blob/master/LICENSE). 5 | -------------------------------------------------------------------------------- /chapter_02/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:pedantic/analysis_options.yaml 5 | 6 | # For lint rules and documentation, see http://dart-lang.github.io/linter/lints. 7 | # Uncomment to specify additional rules. 8 | # linter: 9 | # rules: 10 | # - camel_case_types 11 | 12 | analyzer: 13 | # exclude: 14 | # - path/to/excluded/files/** 15 | -------------------------------------------------------------------------------- /chapter_02/bin/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:introduction_to_dart/01-declaring_variables.dart'; 2 | import 'package:introduction_to_dart/02-strings.dart'; 3 | import 'package:introduction_to_dart/03-functions.dart'; 4 | import 'package:introduction_to_dart/04-classes.dart'; 5 | import 'package:introduction_to_dart/05-generics.dart'; 6 | import 'package:introduction_to_dart/06-collections.dart'; 7 | import 'package:introduction_to_dart/07-higher-order-functions.dart'; 8 | import 'package:introduction_to_dart/08-cascade.dart'; 9 | 10 | // Every Dart program starts 11 | // from this function 12 | main() { 13 | variablePlayground(); 14 | stringPlayground(); 15 | functionPlayground(); 16 | classPlayground(); 17 | genericsPlayground(); 18 | collectionPlayground(); 19 | higherOrderFunctions(); 20 | cascadePlayground(); 21 | } 22 | -------------------------------------------------------------------------------- /chapter_02/lib/01-declaring_variables.dart: -------------------------------------------------------------------------------- 1 | // This a basic function called variablePlayground 2 | // that returns a void, aka - nothing 3 | void variablePlayground() { 4 | basicTypes(); 5 | untypedVariables(); 6 | typeInterpolation(); 7 | immutableVariables(); 8 | } 9 | 10 | // This should look familiar 11 | // to Java developers 12 | void basicTypes() { 13 | int four = 4; 14 | double pi = 3.14; 15 | num someNumber = 24601; 16 | bool yes = true; 17 | bool no = false; 18 | 19 | print(four); 20 | print(pi); 21 | print(someNumber); 22 | print(yes); 23 | print(no); 24 | } 25 | 26 | // This is a get out of jail free card 27 | // from the Dart type systems 28 | // It has its uses, but in most cases, 29 | // it should be avoided 30 | void untypedVariables() { 31 | dynamic something = 14.2; 32 | print(something.runtimeType); 33 | } 34 | 35 | // JavaScript developers should 36 | // recognize this syntax 37 | // Though unlike JavaScript, Dart will 38 | // remember the type that is being assigned to 39 | // these variables 40 | void typeInterpolation() { 41 | var anInteger = 15; 42 | var aDouble = 27.6; 43 | var aBoolean = false; 44 | 45 | print(anInteger.runtimeType); 46 | print(anInteger); 47 | 48 | print(aDouble.runtimeType); 49 | print(aDouble); 50 | 51 | print(aBoolean.runtimeType); 52 | print(aBoolean); 53 | } 54 | 55 | // This is the preferred way to declare variables 56 | // The `final` keyword will only allow you assign 57 | // a variable once. 58 | void immutableVariables() { 59 | final int immutableInteger = 5; 60 | final double immutableDouble = 0.015; 61 | 62 | // Type annotation is optional 63 | final interpolatedInteger = 10; 64 | final interpolatedDouble = 72.8; 65 | 66 | print(interpolatedInteger); 67 | print(interpolatedDouble); 68 | 69 | const aFullySealedVariable = true; 70 | print(aFullySealedVariable); 71 | } 72 | -------------------------------------------------------------------------------- /chapter_02/lib/02-strings.dart: -------------------------------------------------------------------------------- 1 | void stringPlayground() { 2 | basicStringDeclaration(); 3 | multiLineStrings(); 4 | combiningStrings(); 5 | } 6 | 7 | void basicStringDeclaration() { 8 | // With Single Quotes 9 | print('Single quotes'); 10 | final aBoldStatement = 'Dart isn\'t loosely typed.'; 11 | print(aBoldStatement); 12 | 13 | // With Double Quotes 14 | print("Hello, World"); 15 | final aMoreMildOpinion = "Dart's popularity has skyrocketed with Flutter!"; 16 | print(aMoreMildOpinion); 17 | 18 | // Combining single and double quotes 19 | final mixAndMatch = 20 | 'Every programmer should write "Hello, World" when learning a new language.'; 21 | print(mixAndMatch); 22 | } 23 | 24 | void multiLineStrings() { 25 | final withEscaping = 'One Fish\nTwo Fish\nRed Fish\nBlue Fish'; 26 | print(withEscaping); 27 | 28 | final hamlet = ''' 29 | To be, or not to be, that is the question: 30 | Whether 'tis nobler in the mind to suffer 31 | The slings and arrows of outrageous fortune, 32 | Or to take arms against a sea of troubles 33 | And by opposing end them. 34 | '''; 35 | 36 | print(hamlet); 37 | } 38 | 39 | void combiningStrings() { 40 | traditionalConcatenation(); 41 | modernInterpolation(); 42 | } 43 | 44 | void traditionalConcatenation() { 45 | final hello = 'Hello'; 46 | final world = "world"; 47 | 48 | final combined = hello + ' ' + world; 49 | 50 | print(combined); 51 | } 52 | 53 | void modernInterpolation() { 54 | final year = 2011; 55 | final interpolated = 'Dart was announced in $year.'; 56 | print(interpolated); 57 | 58 | final age = 35; 59 | final howOld = 'I am $age ${age == 1 ? 'year' : 'years'} old.'; 60 | print(howOld); 61 | } 62 | -------------------------------------------------------------------------------- /chapter_02/lib/03-functions.dart: -------------------------------------------------------------------------------- 1 | void functionPlayground() { 2 | classicalFunctions(); 3 | optionalParameters(); 4 | consumeClosure(); 5 | } 6 | 7 | /////////////////////////////// 8 | // This should look familiar // 9 | /////////////////////////////// 10 | 11 | void printMyName(String name) { 12 | print('Hello $name'); 13 | } 14 | 15 | int add(int a, int b) { 16 | return a + b; 17 | } 18 | 19 | int factorial(int number) { 20 | if (number <= 0) { 21 | return 1; 22 | } 23 | 24 | return number * factorial(number - 1); 25 | } 26 | 27 | void classicalFunctions() { 28 | printMyName('Anna'); 29 | printMyName('Irina'); 30 | 31 | final sum = add(5, 3); 32 | print(sum); 33 | 34 | print('10 Factorial is ${factorial(10)}'); 35 | } 36 | 37 | /////////////////////////// 38 | // Now for the new stuff // 39 | /////////////////////////// 40 | 41 | // Wrap optional parameters in square brackets 42 | void unnamed([String name, int age]) { 43 | final actualName = name ?? 'Unknown'; 44 | final actualAge = age ?? 0; 45 | print('$actualName is $actualAge years old.'); 46 | } 47 | 48 | // Wrap named optional parameters in curly brackets 49 | void named({String greeting, String name}) { 50 | final actualGreeting = greeting ?? 'Hello'; 51 | final actualName = name ?? 'Mystery Person'; 52 | print('$actualGreeting, $actualName!'); 53 | } 54 | 55 | // You can mix required parameters with optional 56 | // Optional parameters can also have default values 57 | String duplicate(String name, {int times = 1}) { 58 | String merged = ''; 59 | for (int i = 0; i < times; i++) { 60 | merged += name; 61 | if (i != times - 1) { 62 | merged += ' '; 63 | } 64 | } 65 | 66 | return merged; 67 | } 68 | 69 | void optionalParameters() { 70 | unnamed('Huxley', 3); 71 | unnamed(); 72 | 73 | // Notice how parameters can be in any order 74 | // Flutter uses this a lot. You should too. 75 | named(greeting: 'Greetings and Salutations'); 76 | named(name: 'Sonia'); 77 | named(name: 'Alex', greeting: 'Bonjour'); 78 | 79 | final multiply = duplicate('Mikey', times: 3); 80 | print(multiply); 81 | } 82 | 83 | /////////////////// 84 | // Closure Time! // 85 | /////////////////// 86 | 87 | // Define closure types for easy use 88 | typedef int numberGetter(); 89 | 90 | int powerOfTwo({numberGetter getter}) { 91 | return getter() * getter(); 92 | } 93 | 94 | // Or don't define the closure ahead of time 95 | // and just describe it in the function signature 96 | void callbackExample(void callback(String value)) { 97 | callback('Hello Callback'); 98 | } 99 | 100 | void closureInvoker(void Function() aClosure) { 101 | aClosure(); 102 | } 103 | 104 | void consumeClosure() { 105 | final firstClassFunction = () { 106 | print('I am a closure!'); 107 | }; 108 | 109 | closureInvoker(firstClassFunction); 110 | closureInvoker(() { 111 | print('I am written inline'); 112 | }); 113 | 114 | final getFour = () => 4; 115 | final squared = powerOfTwo(getter: getFour); 116 | print(squared); 117 | 118 | callbackExample((result) { 119 | print(result); 120 | }); 121 | } 122 | -------------------------------------------------------------------------------- /chapter_02/lib/04-classes.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | 3 | // An immutable object 4 | class Name { 5 | final String first; 6 | final String last; 7 | 8 | const Name(this.first, this.last); 9 | 10 | @override 11 | bool operator ==(Object other) => 12 | identical(this, other) || 13 | other is Name && 14 | runtimeType == other.runtimeType && 15 | first == other.first && 16 | last == other.last; 17 | 18 | @override 19 | int get hashCode => first.hashCode ^ last.hashCode; 20 | 21 | @override 22 | String toString() { 23 | return '$first $last'; 24 | } 25 | 26 | // Dart has the factory pattern baked into the language 27 | factory Name.fromValues({ 28 | String title, 29 | @required String first, 30 | @required String last, 31 | }) { 32 | // optional properties can be annotated @required, 33 | // but this is just for the IDE, not the language. 34 | // This can enforced with assert statements 35 | assert(first != null); 36 | assert(last != null); 37 | 38 | if (title != null) { 39 | return OfficialName(title, first, last); 40 | } 41 | 42 | return Name(first, last); 43 | } 44 | } 45 | 46 | // A subclass; also immutable 47 | class OfficialName extends Name { 48 | // Private properties begin with an underscore 49 | final String _title; 50 | 51 | // You can add colons after constructor 52 | // to parse data or delegate to super 53 | const OfficialName(this._title, String first, String last) 54 | : super(first, last); 55 | 56 | @override 57 | String toString() { 58 | return '$_title. ${super.toString()}'; 59 | } 60 | } 61 | 62 | // Abstract class in Dart can function the same as Interfaces/Protocols 63 | abstract class Greeter { 64 | String sayHello(); 65 | } 66 | 67 | // Mixins are like Protocol Extensions. 68 | // Here you can define default behaviour 69 | // The only difference if you do not have to define 70 | // an interface beforehand 71 | mixin DefaultedGreeter implements Greeter { 72 | String get name; 73 | 74 | @override 75 | String sayHello() { 76 | return 'Hello $name'; 77 | } 78 | } 79 | 80 | // The 'with' keyword is how you conform to a mixin 81 | class ConcreteGreeter with DefaultedGreeter { 82 | // Putting an underscore before a property 83 | // makes it private 84 | final Name _name; 85 | 86 | ConcreteGreeter(this._name); 87 | 88 | @override 89 | String get name => _name.toString(); 90 | } 91 | 92 | void classPlayground() { 93 | final name = OfficialName('Mr', 'Francois', 'Rabelais'); 94 | final greeter = ConcreteGreeter(name); 95 | final message = greeter.sayHello(); 96 | print(message); 97 | } 98 | -------------------------------------------------------------------------------- /chapter_02/lib/05-generics.dart: -------------------------------------------------------------------------------- 1 | // A basic generic class 2 | // This type can hold anything 3 | class Optional { 4 | final T _value; 5 | T get value => _value; 6 | 7 | const Optional(this._value); 8 | 9 | bool exists() => _value != null; 10 | } 11 | 12 | // A constrained generic class 13 | // Only type that implement the printable interface 14 | // can be used for this class 15 | abstract class Loggable { 16 | void log(); 17 | } 18 | 19 | class LoggableList { 20 | final List loggables; 21 | 22 | LoggableList(this.loggables); 23 | void printAll() { 24 | final Iterable it = [1, 2, 3].where((_) => true); 25 | 26 | for (Loggable logable in loggables) { 27 | logable.log(); 28 | } 29 | } 30 | } 31 | 32 | class LoggableString implements Loggable { 33 | final String text; 34 | 35 | const LoggableString(this.text); 36 | 37 | @override 38 | void log() { 39 | print(text); 40 | } 41 | } 42 | 43 | // A generic function. 44 | // The type is defined between the name of the function 45 | // and the parameter list 46 | T adder(T a, T b) { 47 | return a + b; 48 | } 49 | 50 | void genericsPlayground() { 51 | final a = Optional(10); 52 | final b = Optional(100); 53 | final nothing = Optional(null); 54 | print(a.value); 55 | print(b.value); 56 | print(nothing.exists()); 57 | 58 | // Notice how dart is able to infer the generic type 59 | // You don't always have to be explicit 60 | final strings = List.generate( 61 | 20, 62 | (i) => LoggableString(i.toRadixString(2)), 63 | ); 64 | final list = LoggableList(strings); 65 | list.printAll(); 66 | 67 | final sum = adder(a.value, b.value); 68 | print('Sum is a ${sum.runtimeType} and its value is $sum'); 69 | } 70 | -------------------------------------------------------------------------------- /chapter_02/lib/06-collections.dart: -------------------------------------------------------------------------------- 1 | import 'package:introduction_to_dart/04-classes.dart'; 2 | 3 | void collectionPlayground() { 4 | listPlayground(); 5 | mapPlayground(); 6 | setPlayground(); 7 | collectionControlFlow(); 8 | } 9 | 10 | void listPlayground() { 11 | // Creating with list literal syntax 12 | final numbers = [1, 2, 3, 5, 7]; 13 | 14 | numbers.add(10); 15 | numbers.addAll([4, 1, 35]); 16 | 17 | // Assigning via subscript 18 | numbers[1] = 15; 19 | 20 | print('The second nunber is ${numbers[1]}'); 21 | 22 | // enumerating a list 23 | for (int number in numbers) { 24 | print(number); 25 | } 26 | } 27 | 28 | void mapPlayground() { 29 | // Map Literal syntax 30 | final Map ages = { 31 | 'Mike': 18, 32 | 'Peter': 35, 33 | 'Jennifer': 26, 34 | }; 35 | 36 | // Subscript syntax uses the key type. 37 | // A String in this case 38 | ages['Tom'] = 48; 39 | 40 | final ageOfPeter = ages['Peter']; 41 | print('Peter is $ageOfPeter years old.'); 42 | 43 | ages.remove('Peter'); 44 | 45 | ages.forEach((String name, int age) { 46 | print('$name is $age years old'); 47 | }); 48 | 49 | final james = Name('James', 'Buchanan'); 50 | final brenda = Name('Brenda', 'Fitzpatrick'); 51 | 52 | final namesAndAges = { 53 | james: 83, 54 | brenda: 53, 55 | }; 56 | } 57 | 58 | void setPlayground() { 59 | // Set literal, similar to Map, but no keys 60 | final ministers = {'Justin', 'Stephen', 'Paul', 'Jean', 'Kim', 'Brian'}; 61 | ministers.addAll({'John', 'Pierre', 'Joe', 'Pierre'}); 62 | 63 | // These sort of queries are much faster than Lists 64 | final isJustinAMinister = ministers.contains('Justin'); 65 | print(isJustinAMinister); 66 | 67 | // Notice how 'Pierre' will only be printed once 68 | // In sets, duplicates are automatically rejected 69 | for (String primeMinister in ministers) { 70 | print('$primeMinister is a Prime Minister.'); 71 | } 72 | } 73 | 74 | void collectionControlFlow() { 75 | // Dart now allows you to add control flow inside array declarations 76 | // These language features were developed specifically for Flutter 77 | 78 | // You can now include if states, for loops 79 | // and spread operators inside collections 80 | final addMore = true; 81 | final randomNumbers = [ 82 | 34, 83 | 232, 84 | 54, 85 | 32, 86 | if (addMore) ...[ 87 | 534343, 88 | 4423, 89 | 3432432, 90 | ], 91 | ]; 92 | 93 | final duplicated = [ 94 | for (int number in randomNumbers) number * 2, 95 | for (int i = 0; i < 100; i++) i, 96 | ]; 97 | 98 | print(duplicated); 99 | } 100 | -------------------------------------------------------------------------------- /chapter_02/lib/07-higher-order-functions.dart: -------------------------------------------------------------------------------- 1 | import 'package:introduction_to_dart/04-classes.dart'; 2 | 3 | void higherOrderFunctions() { 4 | final names = mapping(); 5 | names.forEach(print); 6 | 7 | sorting(); 8 | filtering(); 9 | reducing(); 10 | flattening(); 11 | } 12 | 13 | List data = [ 14 | {'first': 'Nada', 'last': 'Mueller', 'age': 10}, 15 | {'first': 'Kurt', 'last': 'Gibbons', 'age': 9}, 16 | {'first': 'Natalya', 'last': 'Compton', 'age': 15}, 17 | {'first': 'Kaycee', 'last': 'Grant', 'age': 20}, 18 | {'first': 'Kody', 'last': 'Ali', 'age': 17}, 19 | {'first': 'Rhodri', 'last': 'Marshall', 'age': 30}, 20 | {'first': 'Kali', 'last': 'Fleming', 'age': 9}, 21 | {'first': 'Steve', 'last': 'Goulding', 'age': 32}, 22 | {'first': 'Ivie', 'last': 'Haworth', 'age': 14}, 23 | {'first': 'Anisha', 'last': 'Bourne', 'age': 40}, 24 | {'first': 'Dominique', 'last': 'Madden', 'age': 31}, 25 | {'first': 'Kornelia', 'last': 'Bass', 'age': 20}, 26 | {'first': 'Saad', 'last': 'Feeney', 'age': 2}, 27 | {'first': 'Eric', 'last': 'Lindsey', 'age': 51}, 28 | {'first': 'Anushka', 'last': 'Harding', 'age': 23}, 29 | {'first': 'Samiya', 'last': 'Allen', 'age': 18}, 30 | {'first': 'Rabia', 'last': 'Merrill', 'age': 6}, 31 | {'first': 'Safwan', 'last': 'Schaefer', 'age': 41}, 32 | {'first': 'Celeste', 'last': 'Aldred', 'age': 34}, 33 | {'first': 'Taio', 'last': 'Mathews', 'age': 17}, 34 | ]; 35 | 36 | List mapping() { 37 | // Transform the data from raw maps to a strongly typed model 38 | final names = data.map((Map rawName) { 39 | final first = rawName['first']; 40 | final last = rawName['last']; 41 | return Name(first, last); 42 | }).toList(); 43 | 44 | return names; 45 | } 46 | 47 | void sorting() { 48 | final names = mapping(); 49 | 50 | // Alphabetize the list by last name 51 | names.sort((a, b) => a.last.compareTo(b.last)); 52 | 53 | print(''); 54 | print('Alphabetical List of Names'); 55 | names.forEach(print); 56 | } 57 | 58 | void filtering() { 59 | final names = mapping(); 60 | final onlyMs = names.where((name) => name.last.startsWith('M')); 61 | 62 | print(''); 63 | print('Filters name list by M'); 64 | onlyMs.forEach(print); 65 | } 66 | 67 | void reducing() { 68 | // Merge an element of the data together 69 | final allAges = data.map((person) => person['age']); 70 | final total = allAges.reduce((total, age) => total + age); 71 | 72 | final average = total / allAges.length; 73 | 74 | print('The average age is $average'); 75 | 76 | final onlyM = data 77 | .map((raw) => Name(raw['first'], raw['last'])) 78 | .where((name) => name.last.startsWith('M')) 79 | .where((name) => name.first.length > 5) 80 | .toList(growable: false); 81 | } 82 | 83 | void flattening() { 84 | // Sometimes you will get collections within collections 85 | // where you'll need flatten the data before you can work 86 | // with it 87 | final matrix = [ 88 | [1, 0, 0], 89 | [0, 0, -1], 90 | [0, 1, 0], 91 | ]; 92 | 93 | final linear = matrix.expand((row) => row); 94 | print(linear); 95 | } 96 | -------------------------------------------------------------------------------- /chapter_02/lib/08-cascade.dart: -------------------------------------------------------------------------------- 1 | class UrlBuilder { 2 | String scheme; 3 | String host; 4 | List routes; 5 | 6 | @override 7 | String toString() { 8 | assert(scheme != null); 9 | assert(host != null); 10 | final paths = [host, if (routes != null) ...routes]; 11 | final path = paths.join('/'); 12 | 13 | return '$scheme://$path'; 14 | } 15 | } 16 | 17 | void cascadePlayground() { 18 | final url = UrlBuilder() 19 | ..scheme = 'https' 20 | ..host = 'dart.dev' 21 | ..routes = [ 22 | 'guides', 23 | 'language', 24 | 'language-tour#cascade-notation-', 25 | ]; 26 | 27 | print(url); 28 | } 29 | 30 | void findLargest() { 31 | // You can even use this operator with objects not designed to be builders. 32 | final largest = [342, 23423, 53, 232, 534] 33 | ..insert(0, 10) 34 | ..sort((a, b) => a.compareTo(b)); 35 | 36 | print('The largest number in the list is ${largest.last}'); 37 | } 38 | -------------------------------------------------------------------------------- /chapter_02/lib/Builder.dart: -------------------------------------------------------------------------------- 1 | class UrlBuilder { 2 | String _scheme; 3 | String _host; 4 | String _path; 5 | 6 | UrlBuilder setScheme(String value) { 7 | _scheme = value; 8 | return this; 9 | } 10 | 11 | UrlBuilder setHost(String value) { 12 | _host = value; 13 | return this; 14 | } 15 | 16 | UrlBuilder setPath(String value) { 17 | _path = value; 18 | return this; 19 | } 20 | 21 | String build() { 22 | assert(_scheme != null); 23 | assert(_host != null); 24 | assert(_path != null); 25 | 26 | return '$_scheme://$_host/$_path'; 27 | } 28 | } 29 | 30 | void usingTheBuilder() { 31 | final url = UrlBuilder() 32 | .setScheme('https') 33 | .setHost('dart.dev') 34 | .setPath('/guides/language/language-tour#cascade-notation-') 35 | .build(); 36 | 37 | print(url); 38 | } 39 | -------------------------------------------------------------------------------- /chapter_02/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: introduction_to_dart 2 | description: A sample command-line application. 3 | # version: 1.0.0 4 | # homepage: https://www.example.com 5 | # author: bkayfitz 6 | 7 | environment: 8 | sdk: '>=2.3.0 <3.0.0' 9 | 10 | #dependencies: 11 | # path: ^1.4.1 12 | 13 | dev_dependencies: 14 | pedantic: ^1.0.0 15 | test: ^1.0.0 16 | -------------------------------------------------------------------------------- /chapter_03/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /chapter_03/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b712a172f9694745f50505c93340883493b505e5 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /chapter_03/README.md: -------------------------------------------------------------------------------- 1 | # flutter_layout 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /chapter_03/assets/LeckerliOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_03/assets/LeckerliOne-Regular.ttf -------------------------------------------------------------------------------- /chapter_03/assets/beach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_03/assets/beach.jpg -------------------------------------------------------------------------------- /chapter_03/assets/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_03/assets/dog.jpg -------------------------------------------------------------------------------- /chapter_03/assets/textiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_03/assets/textiles.jpg -------------------------------------------------------------------------------- /chapter_03/assets/woman_shopping.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_03/assets/woman_shopping.jpg -------------------------------------------------------------------------------- /chapter_03/lib/basic_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_layout/text_layout.dart'; 3 | 4 | class BasicScreen extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Scaffold( 8 | appBar: AppBar( 9 | backgroundColor: Colors.indigo, 10 | title: Text('Welcome to Flutter'), 11 | actions: [ 12 | Padding( 13 | padding: const EdgeInsets.all(10.0), 14 | child: Icon(Icons.edit), 15 | ), 16 | ], 17 | ), 18 | body: Column( 19 | crossAxisAlignment: CrossAxisAlignment.start, 20 | children: [ 21 | Image.asset('assets/beach.jpg'), 22 | TextLayout(), 23 | ], 24 | ), 25 | drawer: Drawer( 26 | child: Container( 27 | color: Colors.lightBlue, 28 | child: Center( 29 | child: Text("I'm a Drawer!"), 30 | ), 31 | ), 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /chapter_03/lib/immutable_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' as Math; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class ImmutableWidget extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | decoration: BoxDecoration(color: Colors.green), 10 | foregroundDecoration: BoxDecoration( 11 | backgroundBlendMode: BlendMode.colorBurn, 12 | gradient: LinearGradient( 13 | begin: Alignment.topCenter, 14 | end: Alignment.bottomCenter, 15 | colors: [ 16 | Color(0xAA0d6123), 17 | Color(0x00000000), 18 | Color(0xAA0d6123), 19 | ], 20 | ), 21 | ), 22 | child: Center( 23 | child: Transform.rotate( 24 | angle: 180 / Math.pi, 25 | child: Container( 26 | width: 250, 27 | height: 250, 28 | decoration: BoxDecoration( 29 | color: Colors.purple, 30 | boxShadow: [ 31 | BoxShadow( 32 | color: Colors.deepPurple.withAlpha(120), 33 | spreadRadius: 4, 34 | blurRadius: 15, 35 | offset: Offset.fromDirection(1.0, 30), 36 | ), 37 | ], 38 | borderRadius: BorderRadius.all(Radius.circular(20)), 39 | ), 40 | child: Padding( 41 | padding: const EdgeInsets.all(50.0), 42 | child: _buildShinyCircle(), 43 | ), 44 | ), 45 | ), 46 | ), 47 | ); 48 | } 49 | 50 | Widget _buildShinyCircle() { 51 | return Container( 52 | decoration: BoxDecoration( 53 | shape: BoxShape.circle, 54 | gradient: RadialGradient( 55 | colors: [ 56 | Colors.lightBlueAccent, 57 | Colors.blueAccent, 58 | ], 59 | center: Alignment(-0.3, -0.5), 60 | ), 61 | boxShadow: [ 62 | BoxShadow(blurRadius: 20), 63 | ], 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /chapter_03/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_layout/e_commerce_screen_after.dart'; 4 | 5 | void main() => runApp(StaticApp()); 6 | 7 | class StaticApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | theme: ThemeData( 12 | brightness: Brightness.dark, 13 | primaryColor: Colors.green, 14 | appBarTheme: AppBarTheme( 15 | elevation: 10, 16 | textTheme: TextTheme( 17 | title: TextStyle( 18 | fontFamily: 'LeckerliOne', 19 | fontSize: 24, 20 | ), 21 | ), 22 | ), 23 | ), 24 | home: ECommerceScreen(), 25 | ); 26 | } 27 | } 28 | 29 | //fontFamily: 'LeckerliOne', 30 | -------------------------------------------------------------------------------- /chapter_03/lib/text_layout.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TextLayout extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Column( 7 | crossAxisAlignment: CrossAxisAlignment.start, 8 | children: [ 9 | Text( 10 | 'Hello, World!', 11 | style: TextStyle(fontFamily: 'LeckerliOne', fontSize: 40), 12 | ), 13 | Text( 14 | 'Text can wrap without issue', 15 | style: Theme.of(context).textTheme.title, 16 | ), 17 | Text( 18 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam at mauris massa. Suspendisse potenti. Aenean aliquet eu nisl vitae tempus.'), 19 | Divider(), 20 | RichText( 21 | text: TextSpan( 22 | text: 'Flutter text is ', 23 | style: TextStyle(fontSize: 22, color: Colors.black), 24 | children: [ 25 | TextSpan( 26 | text: 'really ', 27 | style: TextStyle( 28 | fontWeight: FontWeight.bold, 29 | color: Colors.red, 30 | ), 31 | children: [ 32 | TextSpan( 33 | text: 'powerful.', 34 | style: TextStyle( 35 | decoration: TextDecoration.underline, 36 | decorationStyle: TextDecorationStyle.double, 37 | fontSize: 40, 38 | ), 39 | ), 40 | ], 41 | ), 42 | ], 43 | ), 44 | ) 45 | ], 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chapter_03/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_layout 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.3.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://dart.dev/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | uses-material-design: true 38 | fonts: 39 | - family: LeckerliOne 40 | fonts: 41 | - asset: assets/LeckerliOne-Regular.ttf 42 | assets: 43 | - assets/ 44 | 45 | -------------------------------------------------------------------------------- /chapter_04/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /chapter_04/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 20e59316b8b8474554b38493b8ca888794b0234a 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /chapter_04/README.md: -------------------------------------------------------------------------------- 1 | # stopwatch 2 | 3 | A new Flutter application. 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /chapter_04/lib/deep_tree.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DeepTree extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | body: SafeArea( 8 | child: Column( 9 | mainAxisAlignment: MainAxisAlignment.center, 10 | children: [ 11 | Row( 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | FlutterLogo(), 15 | Text('Flutter is amazing.'), 16 | ], 17 | ), 18 | Expanded( 19 | child: Container( 20 | color: Colors.purple, 21 | ), 22 | ), 23 | Text('Its all widgets!'), 24 | Text('Let\'s find out how deep the rabbit hole goes.'), 25 | ], 26 | ), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /chapter_04/lib/profile_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_layout/star.dart'; 3 | 4 | class ProfileScreen extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Scaffold( 8 | body: Stack( 9 | children: [ 10 | Image.asset('assets/beach.jpg'), 11 | Transform.translate( 12 | offset: Offset(0, 100), 13 | child: Column( 14 | children: [ 15 | _buildProfileImage(context), 16 | _buildProfileDetails(context), 17 | _buildActions(context), 18 | ], 19 | ), 20 | ), 21 | ], 22 | ), 23 | ); 24 | } 25 | 26 | Widget _buildProfileImage(BuildContext context) { 27 | return Container( 28 | width: 200, 29 | height: 200, 30 | child: ClipOval( 31 | child: Image.asset( 32 | 'assets/dog.jpg', 33 | fit: BoxFit.fitWidth, 34 | ), 35 | ), 36 | ); 37 | } 38 | 39 | Widget _buildProfileDetails(BuildContext context) { 40 | return Padding( 41 | padding: const EdgeInsets.all(20.0), 42 | child: Column( 43 | crossAxisAlignment: CrossAxisAlignment.start, 44 | children: [ 45 | Text( 46 | 'Wolfram Barkovich', 47 | style: TextStyle(fontSize: 35, fontWeight: FontWeight.w600), 48 | ), 49 | StarRating( 50 | value: 5, 51 | ), 52 | _buildDetailsRow('Age', '4'), 53 | _buildDetailsRow('Status', 'Good Boy'), 54 | ], 55 | ), 56 | ); 57 | } 58 | 59 | Widget _buildDetailsRow(String heading, String value) { 60 | return Row( 61 | children: [ 62 | Text( 63 | '$heading: ', 64 | style: TextStyle(fontWeight: FontWeight.bold), 65 | ), 66 | Text(value), 67 | ], 68 | ); 69 | } 70 | 71 | Widget _buildActions(BuildContext context) { 72 | return Row( 73 | mainAxisAlignment: MainAxisAlignment.center, 74 | children: [ 75 | _buildIcon(Icons.restaurant, 'Feed'), 76 | _buildIcon(Icons.favorite, 'Pet'), 77 | _buildIcon(Icons.directions_walk, 'Walk'), 78 | ], 79 | ); 80 | } 81 | 82 | Widget _buildIcon(IconData icon, String text) { 83 | return Padding( 84 | padding: const EdgeInsets.all(20.0), 85 | child: Column( 86 | children: [ 87 | Icon( 88 | icon, 89 | size: 40, 90 | ), 91 | Text(text) 92 | ], 93 | ), 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /chapter_04/lib/star.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Star extends StatelessWidget { 4 | final Color color; 5 | final double size; 6 | 7 | const Star({ 8 | Key key, 9 | this.color, 10 | this.size, 11 | }) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return SizedBox( 16 | width: size, 17 | height: size, 18 | child: CustomPaint( 19 | painter: _StarPainter(color), 20 | ), 21 | ); 22 | } 23 | } 24 | 25 | class _StarPainter extends CustomPainter { 26 | final Color color; 27 | 28 | _StarPainter(this.color); 29 | 30 | @override 31 | void paint(Canvas canvas, Size size) { 32 | final paint = Paint()..color = color; 33 | 34 | final path = Path(); 35 | 36 | path.moveTo(size.width * 0.5, 0); 37 | path.lineTo(size.width * 0.618, size.height * 0.382); 38 | path.lineTo(size.width, size.height * 0.382); 39 | path.lineTo(size.width * 0.691, size.height * 0.618); 40 | path.lineTo(size.width * 0.809, size.height); 41 | path.lineTo(size.width * 0.5, size.height * 0.7639); 42 | path.lineTo(size.width * 0.191, size.height); 43 | path.lineTo(size.width * 0.309, size.height * 0.618); 44 | path.lineTo(size.width * 0.309, size.height * 0.618); 45 | path.lineTo(0, size.height * 0.382); 46 | path.lineTo(size.width * 0.382, size.height * 0.382); 47 | 48 | path.close(); 49 | 50 | canvas.drawPath(path, paint); 51 | } 52 | 53 | @override 54 | bool shouldRepaint(CustomPainter oldDelegate) { 55 | return false; 56 | } 57 | } 58 | 59 | class StarRating extends StatelessWidget { 60 | final Color color; 61 | final int value; 62 | final double starSize; 63 | 64 | const StarRating({ 65 | Key key, 66 | @required this.value, 67 | this.color = Colors.deepOrange, 68 | this.starSize = 25, 69 | }) : super(key: key); 70 | 71 | @override 72 | Widget build(BuildContext context) { 73 | return Row( 74 | children: List.generate( 75 | value, 76 | (_) => Padding( 77 | padding: const EdgeInsets.all(2.0), 78 | child: Star( 79 | color: color, 80 | size: starSize, 81 | ), 82 | ), 83 | ), 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /chapter_04/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: stopwatch 2 | description: A new Flutter application. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.2.2 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://dart.dev/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /chapter_05/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /chapter_05/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 20e59316b8b8474554b38493b8ca888794b0234a 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /chapter_05/README.md: -------------------------------------------------------------------------------- 1 | # master_plan 2 | 3 | A new Flutter application. 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /chapter_05/lib/login_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'stopwatch.dart'; 3 | 4 | class LoginScreen extends StatefulWidget { 5 | static const route = '/login'; 6 | @override 7 | _LoginScreenState createState() => _LoginScreenState(); 8 | } 9 | 10 | class _LoginScreenState extends State { 11 | String name; 12 | final _nameController = TextEditingController(); 13 | final _emailController = TextEditingController(); 14 | final _formKey = GlobalKey(); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: Text('Login'), 21 | ), 22 | body: Center( 23 | child: _buildLoginForm(), 24 | ), 25 | ); 26 | } 27 | 28 | Widget _buildLoginForm() { 29 | return Form( 30 | key: _formKey, 31 | child: Padding( 32 | padding: const EdgeInsets.all(20.0), 33 | child: Column( 34 | mainAxisAlignment: MainAxisAlignment.center, 35 | children: [ 36 | TextFormField( 37 | controller: _nameController, 38 | decoration: InputDecoration(labelText: 'Runner'), 39 | validator: (text) => 40 | text.isEmpty ? 'Enter the runner\'s name.' : null, 41 | ), 42 | TextFormField( 43 | controller: _emailController, 44 | keyboardType: TextInputType.emailAddress, 45 | decoration: InputDecoration(labelText: 'Email'), 46 | validator: (text) { 47 | if (text.isEmpty) { 48 | return 'Enter the runner\'s email.'; 49 | } 50 | 51 | final regex = RegExp('[^@]+@[^\.]+\..+'); 52 | if (!regex.hasMatch(text)) { 53 | return 'Enter a valid email'; 54 | } 55 | 56 | return null; 57 | }, 58 | ), 59 | SizedBox(height: 20), 60 | ElevatedButton( 61 | child: Text('Continue'), 62 | onPressed: _validate, 63 | ), 64 | ], 65 | ))); 66 | } 67 | 68 | void _validate() { 69 | final form = _formKey.currentState; 70 | if (!form.validate()) { 71 | return; 72 | } 73 | final name = _nameController.text; 74 | final email = _emailController.text; 75 | 76 | Navigator.of(context).pushReplacementNamed( 77 | StopWatch.route, 78 | arguments: name, 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /chapter_05/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:stopwatch/login_screen.dart'; 3 | import './stopwatch.dart'; 4 | 5 | void main() => runApp(StopwatchApp()); 6 | 7 | class StopwatchApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | routes: { 12 | '/': (context) => LoginScreen(), 13 | LoginScreen.route: (context) => LoginScreen(), 14 | StopWatch.route: (context) => StopWatch(), 15 | }, 16 | initialRoute: '/', 17 | 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter_05/lib/platform_alert.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | 4 | class PlatformAlert { 5 | final String title; 6 | final String message; 7 | 8 | const PlatformAlert({@required this.title, @required this.message}) 9 | : assert(title != null), 10 | assert(message != null); 11 | void show(BuildContext context) { 12 | final platform = Theme.of(context).platform; 13 | 14 | if (platform == TargetPlatform.iOS) { 15 | _buildCupertinoAlert(context); 16 | } else { 17 | _buildMaterialAlert(context); 18 | } 19 | } 20 | 21 | void _buildMaterialAlert(BuildContext context) { 22 | showDialog( 23 | context: context, 24 | builder: (context) { 25 | return AlertDialog( 26 | title: Text(title), 27 | content: Text(message), 28 | actions: [ 29 | TextButton( 30 | child: Text('Close'), 31 | onPressed: () => Navigator.of(context).pop()) 32 | ]); 33 | }); 34 | } 35 | 36 | void _buildCupertinoAlert(BuildContext context) { 37 | showCupertinoDialog( 38 | context: context, 39 | builder: (context) { 40 | return CupertinoAlertDialog( 41 | title: Text(title), 42 | content: Text(message), 43 | actions: [ 44 | CupertinoButton( 45 | child: Text('Close'), 46 | onPressed: () => Navigator.of(context).pop()) 47 | ]); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /chapter_05/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: master_plan 2 | description: A new Flutter application. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://dart.dev/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /chapter_06/lib/controllers/plan_controller.dart: -------------------------------------------------------------------------------- 1 | import '../services/plan_services.dart'; 2 | import '../models/data_layer.dart'; 3 | 4 | class PlanController { 5 | final services = PlanServices(); 6 | 7 | // This public getter cannot be modified by any other object 8 | List get plans => List.unmodifiable(services.getAllPlans()); 9 | 10 | void addNewPlan(String name) { 11 | if (name.isEmpty) { 12 | return; 13 | } 14 | name = _checkForDuplicates(plans.map((plan) => plan.name), name); 15 | services.createPlan(name); 16 | } 17 | 18 | void savePlan(Plan plan) { 19 | services.savePlan(plan); 20 | } 21 | 22 | void deletePlan(Plan plan) { 23 | services.delete(plan); 24 | } 25 | 26 | void createNewTask(Plan plan, [String description]) { 27 | if (description == null || description.isEmpty) { 28 | description = 'New Task'; 29 | } 30 | 31 | description = _checkForDuplicates( 32 | plan.tasks.map((task) => task.description), description); 33 | 34 | services.addTask(plan, description); 35 | } 36 | 37 | void deleteTask(Plan plan, Task task) { 38 | services.deleteTask(plan, task); 39 | } 40 | 41 | String _checkForDuplicates(Iterable items, String text) { 42 | final duplicatedCount = items.where((item) => item.contains(text)).length; 43 | if (duplicatedCount > 0) { 44 | text += ' ${duplicatedCount + 1}'; 45 | } 46 | 47 | return text; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /chapter_06/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'plan_provider.dart'; 3 | import 'views/plan_creator_screen.dart'; 4 | 5 | void main() => runApp(PlanProvider(child: MasterPlanApp())); 6 | 7 | class MasterPlanApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | theme: ThemeData(primarySwatch: Colors.purple), 12 | home: PlanCreatorScreen(), 13 | ); 14 | } 15 | } -------------------------------------------------------------------------------- /chapter_06/lib/models/data_layer.dart: -------------------------------------------------------------------------------- 1 | export 'plan.dart'; 2 | export 'task.dart'; -------------------------------------------------------------------------------- /chapter_06/lib/models/plan.dart: -------------------------------------------------------------------------------- 1 | import '../repositories/repository.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import './task.dart'; 4 | 5 | class Plan { 6 | final int id; 7 | String name = ''; 8 | List tasks = []; 9 | 10 | Plan({@required this.id, this.name = ''}); 11 | 12 | Plan.fromModel(Model model) 13 | : id = model.id, 14 | name = model?.data['name'], 15 | tasks = model?.data['task'] 16 | ?.map((task) => Task.fromModel(task)) 17 | ?.toList() ?? 18 | []; 19 | 20 | Model toModel() => Model(id: id, data: { 21 | 'name': name, 22 | 'tasks': tasks.map((task) => task.toModel()).toList() 23 | }); 24 | 25 | int get completeCount => tasks.where((task) => task.complete).length; 26 | 27 | String get completenessMessage => 28 | '$completeCount out of ${tasks.length} tasks'; 29 | } 30 | -------------------------------------------------------------------------------- /chapter_06/lib/models/task.dart: -------------------------------------------------------------------------------- 1 | import '../repositories/repository.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | 4 | class Task { 5 | final int id; 6 | String description; 7 | bool complete; 8 | 9 | Task({ 10 | @required this.id, 11 | this.complete = false, 12 | this.description = '', 13 | }); 14 | 15 | Task.fromModel(Model model) 16 | : id = model.id, 17 | description = model.data['description'], 18 | complete = model.data['complete']; 19 | 20 | Model toModel() => 21 | Model(id: id, data: {'description': description, 'complete': complete}); 22 | } 23 | -------------------------------------------------------------------------------- /chapter_06/lib/plan_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'controllers/plan_controller.dart'; 3 | 4 | class PlanProvider extends InheritedWidget { 5 | final _controller = PlanController(); 6 | 7 | PlanProvider({Key key, Widget child}) : super(key: key, child: child); 8 | 9 | @override 10 | bool updateShouldNotify(InheritedWidget oldWidget) => false; 11 | 12 | static PlanController of(BuildContext context) { 13 | PlanProvider provider = context.dependOnInheritedWidgetOfExactType(); 14 | return provider._controller; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter_06/lib/repositories/in_memory_cache.dart: -------------------------------------------------------------------------------- 1 | import 'repository.dart'; 2 | 3 | class InMemoryCache implements Repository { 4 | final _storage = Map(); 5 | 6 | @override 7 | Model create() { 8 | final ids = _storage.keys.toList()..sort(); 9 | 10 | final id = (ids.length == 0) ? 1 : ids.last + 1; 11 | 12 | final model = Model(id: id); 13 | _storage[id] = model; 14 | return model; 15 | } 16 | 17 | @override 18 | Model get(int id) { 19 | return _storage[id]; 20 | } 21 | 22 | @override 23 | List getAll() { 24 | return _storage.values.toList(growable: false); 25 | } 26 | 27 | @override 28 | void update(Model item) { 29 | _storage[item.id] = item; 30 | } 31 | 32 | @override 33 | void delete(Model item) { 34 | _storage.remove(item.id); 35 | } 36 | 37 | @override 38 | void clear() { 39 | _storage.clear(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /chapter_06/lib/repositories/repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | abstract class Repository { 4 | Model create(); 5 | 6 | List getAll(); 7 | Model get(int id); 8 | void update(Model item); 9 | 10 | void delete(Model item); 11 | void clear(); 12 | } 13 | 14 | class Model { 15 | final int id; 16 | final Map data; 17 | 18 | const Model({ 19 | @required this.id, 20 | this.data = const {}, 21 | }); 22 | } -------------------------------------------------------------------------------- /chapter_06/lib/services/plan_services.dart: -------------------------------------------------------------------------------- 1 | import '../models/data_layer.dart'; 2 | import '../repositories/in_memory_cache.dart'; 3 | import '../repositories/repository.dart'; 4 | 5 | class PlanServices { 6 | Repository _repository = InMemoryCache(); 7 | 8 | Plan createPlan(String name) { 9 | final model = _repository.create(); 10 | final plan = Plan.fromModel(model)..name = name; 11 | savePlan(plan); 12 | return plan; 13 | } 14 | 15 | void savePlan(Plan plan) { 16 | _repository.update(plan.toModel()); 17 | } 18 | 19 | void delete(Plan plan) { 20 | _repository.delete(plan.toModel()); 21 | } 22 | 23 | List getAllPlans() { 24 | return _repository 25 | .getAll() 26 | .map((model) => Plan.fromModel(model)) 27 | .toList(); 28 | } 29 | 30 | void addTask(Plan plan, String description) { 31 | final id = plan.tasks.last?.id ?? 0 + 1; 32 | final task = Task(id: id, description: description); 33 | plan.tasks.add(task); 34 | savePlan(plan); 35 | } 36 | 37 | void deleteTask(Plan plan, Task task) { 38 | plan.tasks.remove(task); 39 | savePlan(plan); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /chapter_06/lib/views/plan_creator_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../plan_provider.dart'; 4 | import 'plan_screen.dart'; 5 | 6 | class PlanCreatorScreen extends StatefulWidget { 7 | @override 8 | _PlanCreatorScreenState createState() => _PlanCreatorScreenState(); 9 | } 10 | 11 | class _PlanCreatorScreenState extends State { 12 | final textController = TextEditingController(); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar(title: Text('Master Plans')), 18 | body: Column(children: [ 19 | _buildListCreator(), 20 | Expanded(child: _buildMasterPlans()) 21 | ]), 22 | ); 23 | } 24 | 25 | @override 26 | void dispose() { 27 | textController.dispose(); 28 | super.dispose(); 29 | } 30 | 31 | Widget _buildListCreator() { 32 | return Padding( 33 | padding: const EdgeInsets.all(20.0), 34 | child: Material( 35 | color: Theme.of(context).cardColor, 36 | elevation: 10, 37 | child: TextField( 38 | controller: textController, 39 | decoration: InputDecoration( 40 | labelText: 'Add a plan', contentPadding: EdgeInsets.all(20)), 41 | onEditingComplete: addPlan), 42 | )); 43 | } 44 | 45 | void addPlan() { 46 | final text = textController.text; 47 | // All the business logic has been removed from this 'view' method! 48 | final controller = PlanProvider.of(context); 49 | controller.addNewPlan(text); 50 | 51 | textController.clear(); 52 | FocusScope.of(context).requestFocus(FocusNode()); 53 | setState(() {}); 54 | } 55 | 56 | Widget _buildMasterPlans() { 57 | final plans = PlanProvider.of(context).plans; 58 | 59 | if (plans.isEmpty) { 60 | return Column( 61 | mainAxisAlignment: MainAxisAlignment.center, 62 | children: [ 63 | Icon(Icons.note, size: 100, color: Colors.grey), 64 | Text('You do not have any plans yet.', 65 | style: Theme.of(context).textTheme.headline5) 66 | ]); 67 | } 68 | 69 | return ListView.builder( 70 | itemCount: plans.length, 71 | itemBuilder: (context, index) { 72 | final plan = plans[index]; 73 | return Dismissible( 74 | key: ValueKey(plan), 75 | background: Container(color: Colors.red), 76 | direction: DismissDirection.endToStart, 77 | onDismissed: (_) { 78 | final controller = PlanProvider.of(context); 79 | controller.deletePlan(plan); 80 | setState(() {}); 81 | }, 82 | child: ListTile( 83 | title: Text(plan.name), 84 | subtitle: Text(plan.completenessMessage), 85 | onTap: () { 86 | Navigator.of(context).push(MaterialPageRoute( 87 | builder: (_) => PlanScreen(plan: plan))); 88 | }), 89 | ); 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /chapter_06/lib/views/plan_screen.dart: -------------------------------------------------------------------------------- 1 | import '../models/data_layer.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../plan_provider.dart'; 5 | 6 | class PlanScreen extends StatefulWidget { 7 | final Plan plan; 8 | const PlanScreen({Key key, this.plan}) : super(key: key); 9 | @override 10 | State createState() => _PlanScreenState(); 11 | } 12 | 13 | class _PlanScreenState extends State { 14 | ScrollController scrollController; 15 | Plan get plan => widget.plan; 16 | @override 17 | void initState() { 18 | super.initState(); 19 | scrollController = ScrollController() 20 | ..addListener(() { 21 | FocusScope.of(context).requestFocus(FocusNode()); 22 | }); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | // final plan = PlanProvider.of(context); 28 | return Scaffold( 29 | appBar: AppBar(title: Text('Master Plan')), 30 | body: Column(children: [ 31 | Expanded(child: _buildList()), 32 | SafeArea(child: Text(plan.completenessMessage)) 33 | ]), 34 | floatingActionButton: _buildAddTaskButton()); 35 | } 36 | 37 | @override 38 | void dispose() { 39 | scrollController.dispose(); 40 | super.dispose(); 41 | } 42 | 43 | Widget _buildAddTaskButton() { 44 | //final plan = PlanProvider.of(context); 45 | return FloatingActionButton( 46 | child: Icon(Icons.add), 47 | onPressed: () { 48 | final controller = PlanProvider.of(context); 49 | controller.createNewTask(plan); 50 | setState(() {}); 51 | }, 52 | ); 53 | } 54 | 55 | Widget _buildList() { 56 | //final plan = PlanProvider.of(context); 57 | return ListView.builder( 58 | controller: scrollController, 59 | itemCount: plan.tasks.length, 60 | itemBuilder: (context, index) => _buildTaskTile(plan.tasks[index]), 61 | ); 62 | } 63 | 64 | Widget _buildTaskTile(Task task) { 65 | return Dismissible( 66 | key: ValueKey(task), 67 | background: Container(color: Colors.red), 68 | direction: DismissDirection.endToStart, 69 | onDismissed: (_) { 70 | final controller = PlanProvider.of(context); 71 | controller.deleteTask(plan, task); 72 | setState(() {}); 73 | }, 74 | child: ListTile( 75 | leading: Checkbox( 76 | value: task.complete, 77 | onChanged: (selected) { 78 | setState(() { 79 | task.complete = selected; 80 | }); 81 | }), 82 | title: TextFormField( 83 | initialValue: task.description, 84 | onFieldSubmitted: (text) { 85 | setState(() { 86 | task.description = text; 87 | }); 88 | }, 89 | ), 90 | ), 91 | ); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /chapter_06/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cookbook_ch_6 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.2 31 | 32 | dev_dependencies: 33 | flutter_test: 34 | sdk: flutter 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | 47 | # To add assets to your application, add an assets section, like this: 48 | # assets: 49 | # - images/a_dot_burr.jpeg 50 | # - images/a_dot_ham.jpeg 51 | 52 | # An image asset can refer to one or more resolution-specific "variants", see 53 | # https://flutter.dev/assets-and-images/#resolution-aware. 54 | 55 | # For details regarding adding assets from package dependencies, see 56 | # https://flutter.dev/assets-and-images/#from-packages 57 | 58 | # To add custom fonts to your application, add a fonts section here, 59 | # in this "flutter" section. Each entry in this list should have a 60 | # "family" key with the font family name, and a "fonts" key with a 61 | # list giving the asset and other descriptors for the font. For 62 | # example: 63 | # fonts: 64 | # - family: Schyler 65 | # fonts: 66 | # - asset: fonts/Schyler-Regular.ttf 67 | # - asset: fonts/Schyler-Italic.ttf 68 | # style: italic 69 | # - family: Trajan Pro 70 | # fonts: 71 | # - asset: fonts/TrajanPro.ttf 72 | # - asset: fonts/TrajanPro_Bold.ttf 73 | # weight: 700 74 | # 75 | # For details regarding fonts from package dependencies, 76 | # see https://flutter.dev/custom-fonts/#from-packages 77 | -------------------------------------------------------------------------------- /chapter_07/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: lines_longer_than_80_chars 6 | 7 | import 'package:geolocator_web/geolocator_web.dart'; 8 | 9 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 10 | 11 | // ignore: public_member_api_docs 12 | void registerPlugins(Registrar registrar) { 13 | GeolocatorPlugin.registerWith(registrar); 14 | registrar.registerMessageHandler(); 15 | } 16 | -------------------------------------------------------------------------------- /chapter_07/lib/location_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:geolocator/geolocator.dart'; 3 | 4 | class LocationScreen extends StatefulWidget { 5 | @override 6 | _LocationScreenState createState() => _LocationScreenState(); 7 | } 8 | 9 | class _LocationScreenState extends State { 10 | String myPosition = ''; 11 | @override 12 | void initState() { 13 | getPosition().then((Position myPos) { 14 | myPosition = 'Latitude: ' + myPos.latitude.toString() + ' - Longitude: ' + myPos.longitude.toString(); 15 | setState(() { 16 | myPosition = myPosition; 17 | }); 18 | }); 19 | super.initState(); 20 | } 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return Scaffold( 25 | appBar: AppBar(title: Text('Current Location')), 26 | body: Center(child:Text(myPosition)), 27 | ); 28 | } 29 | 30 | Future getPosition() async { 31 | Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); 32 | return position; 33 | } 34 | } -------------------------------------------------------------------------------- /chapter_07/lib/navigation_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NavigationDialog extends StatefulWidget { 4 | @override 5 | _NavigationDialogState createState() => _NavigationDialogState(); 6 | } 7 | 8 | class _NavigationDialogState extends State { 9 | Color color = Colors.blue[700]; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | backgroundColor: color, 14 | appBar: AppBar( 15 | title: Text('Navigation Dialog Screen'), 16 | ), 17 | body: Center( 18 | child: ElevatedButton( 19 | child: Text('Change Color'), 20 | onPressed: () { 21 | _showColorDialog(context); 22 | }), 23 | ), 24 | ); 25 | } 26 | 27 | _showColorDialog(BuildContext context) async { 28 | color = null; 29 | await showDialog( 30 | barrierDismissible: false, 31 | context: context, 32 | builder: (_) { 33 | return AlertDialog( 34 | title: Text('Very important question'), 35 | content: Text('Please choose a color'), 36 | actions: [ 37 | TextButton( 38 | child: Text('Red'), 39 | onPressed: () { 40 | color = Colors.red[700]; 41 | Navigator.pop(context, color); 42 | }), 43 | TextButton( 44 | child: Text('Green'), 45 | onPressed: () { 46 | color = Colors.green[700]; 47 | Navigator.pop(context, color); 48 | }), 49 | TextButton( 50 | child: Text('Blue'), 51 | onPressed: () { 52 | color = Colors.blue[700]; 53 | Navigator.pop(context, color); 54 | }), 55 | ], 56 | ); 57 | }, 58 | ); 59 | setState(() { 60 | color = color; 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /chapter_07/lib/navigation_first.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'navigation_second.dart'; 4 | 5 | class NavigationFirst extends StatefulWidget { 6 | @override 7 | _NavigationFirstState createState() => _NavigationFirstState(); 8 | } 9 | 10 | class _NavigationFirstState extends State { 11 | Color color = Colors.blue[700]; 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | backgroundColor: color, 16 | appBar: AppBar( 17 | title: Text('Navigation First Screen'), 18 | ), 19 | body: Center( 20 | child: ElevatedButton( 21 | child: Text('Change Color'), 22 | onPressed: () { 23 | _navigateAndGetColor(context); 24 | }), 25 | ), 26 | ); 27 | } 28 | 29 | _navigateAndGetColor(BuildContext context) async { 30 | color = await Navigator.push( 31 | context, 32 | MaterialPageRoute(builder: (context) => NavigationSecond()), 33 | ); 34 | setState(() { 35 | color = color; 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /chapter_07/lib/navigation_second.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NavigationSecond extends StatefulWidget { 4 | @override 5 | _NavigationSecondState createState() => _NavigationSecondState(); 6 | } 7 | 8 | class _NavigationSecondState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | Color color; 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text('Navigation Second Screen'), 15 | ), 16 | body: Center( 17 | child: Column( 18 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 19 | children: [ 20 | ElevatedButton( 21 | child: Text('Red'), 22 | onPressed: () { 23 | color = Colors.red[700]; 24 | Navigator.pop(context, color); 25 | }), 26 | ElevatedButton( 27 | child: Text('Green'), 28 | onPressed: () { 29 | color = Colors.green[700]; 30 | Navigator.pop(context, color); 31 | }), 32 | ElevatedButton( 33 | child: Text('Blue'), 34 | onPressed: () { 35 | color = Colors.blue[700]; 36 | Navigator.pop(context, color); 37 | }), 38 | ], 39 | ), 40 | )); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /chapter_08/assets/pizzalist.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "pizzaName": "Margherita", 5 | "description": "Pizza with tomato, fresh mozzarella and basil", 6 | "price": 8.75, 7 | "imageUrl": "images/margherita.png" 8 | }, 9 | { 10 | "id": 2, 11 | "pizzaName": "Marinara", 12 | "description": "Pizza with tomato, garlic and oregano", 13 | "price": 7.50, 14 | "imageUrl": "images/marinara.png" 15 | }, 16 | { 17 | "id": 3, 18 | "pizzaName": "Napoli", 19 | "description": "Pizza with tomato, garlic and anchovies", 20 | "price": 9.50, 21 | "imageUrl": "images/marinara.png" 22 | }, 23 | { 24 | "id": 4, 25 | "pizzaName": "Carciofi", 26 | "description": "Pizza with tomato, fresh mozzarella and artichokes", 27 | "price": 8.80, 28 | "imageUrl": "images/marinara.png" 29 | }, 30 | { 31 | "id": 5, 32 | "pizzaName": "Bufala", 33 | "description": "Pizza with tomato, buffalo mozzarella and basil", 34 | "price": 12.50, 35 | "imageUrl": "images/marinara.png" 36 | } 37 | ] -------------------------------------------------------------------------------- /chapter_08/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: lines_longer_than_80_chars 6 | 7 | import 'package:shared_preferences_web/shared_preferences_web.dart'; 8 | 9 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 10 | 11 | // ignore: public_member_api_docs 12 | void registerPlugins(Registrar registrar) { 13 | SharedPreferencesPlugin.registerWith(registrar); 14 | registrar.registerMessageHandler(); 15 | } 16 | -------------------------------------------------------------------------------- /chapter_08/lib/httphelper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:http/http.dart' as http; 3 | import 'dart:convert'; 4 | import 'pizza.dart'; 5 | 6 | class HttpHelper { 7 | final String authority = '02z2g.mocklab.io'; 8 | final String path = 'pizzalist'; 9 | final String postPath = 'pizza'; 10 | final String putPath = 'pizza'; 11 | final String deletePath = 'pizza'; 12 | 13 | Future> getPizzaList() async { 14 | Uri url = Uri.https(authority, path); 15 | http.Response result = await http.get(url); 16 | if (result.statusCode == HttpStatus.ok) { 17 | final jsonResponse = json.decode(result.body); 18 | //provide a type argument to the map method to avoid type error 19 | List pizzas = 20 | jsonResponse.map((i) => Pizza.fromJson(i)).toList(); 21 | return pizzas; 22 | } else { 23 | return []; 24 | } 25 | } 26 | 27 | Future postPizza(Pizza pizza) async { 28 | String post = json.encode(pizza.toJson()); 29 | Uri url = Uri.https(authority, postPath); 30 | http.Response r = await http.post( 31 | url, 32 | body: post, 33 | ); 34 | return r.body; 35 | } 36 | 37 | Future putPizza(Pizza pizza) async { 38 | String put = json.encode(pizza.toJson()); 39 | Uri url = Uri.https(authority, putPath); 40 | http.Response r = await http.put( 41 | url, 42 | body: put, 43 | ); 44 | return r.body; 45 | } 46 | 47 | Future deletePizza(int id) async { 48 | Uri url = Uri.https(authority, deletePath); 49 | http.Response r = await http.delete( 50 | url, 51 | ); 52 | return r.body; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /chapter_08/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_secure_storage/flutter_secure_storage.dart'; 3 | import 'package:store_data/pizza.dart'; 4 | 5 | import 'httphelper.dart'; 6 | import 'pizza_detail.dart'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | title: 'Flutter Demo', 17 | theme: ThemeData( 18 | primarySwatch: Colors.deepPurple, 19 | visualDensity: VisualDensity.adaptivePlatformDensity, 20 | ), 21 | home: MyHomePage(), 22 | ); 23 | } 24 | } 25 | 26 | class MyHomePage extends StatefulWidget { 27 | @override 28 | _MyHomePageState createState() => _MyHomePageState(); 29 | } 30 | 31 | class _MyHomePageState extends State { 32 | final storage = FlutterSecureStorage(); 33 | final myKey = 'myPass'; 34 | final pwdController = TextEditingController(); 35 | String myPass = ''; 36 | 37 | @override 38 | void initState() { 39 | callPizzas(); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | floatingActionButton: FloatingActionButton( 47 | child: Icon(Icons.add), 48 | onPressed: () { 49 | Navigator.push( 50 | context, 51 | MaterialPageRoute(builder: (context) => PizzaDetail()), 52 | ); 53 | }), 54 | ); 55 | } 56 | 57 | Future writeToSecureStorage() async { 58 | await storage.write(key: myKey, value: pwdController.text); 59 | } 60 | 61 | Future readFromSecureStorage() async { 62 | String secret = await storage.read(key: myKey); 63 | return secret; 64 | } 65 | 66 | Future> callPizzas() async { 67 | HttpHelper helper = HttpHelper(); 68 | List pizzas = await helper.getPizzaList(); 69 | return pizzas; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /chapter_08/lib/pizza.dart: -------------------------------------------------------------------------------- 1 | const keyId = 'id'; 2 | const keyName = 'pizzaName'; 3 | const keyDescription = 'description'; 4 | const keyPrice = 'price'; 5 | const keyImage = 'imageUrl'; 6 | 7 | class Pizza { 8 | int id; 9 | String pizzaName; 10 | String description; 11 | double price; 12 | String imageUrl; 13 | 14 | Pizza(); 15 | 16 | Pizza.fromJson(Map json) { 17 | this.id = (json[keyId] != null) ? int.tryParse(json['id'].toString()) : 0; 18 | this.pizzaName = (json[keyName] != null) ? json[keyName].toString() : ''; 19 | this.description = 20 | (json[keyDescription] != null) ? json[keyDescription].toString() : ''; 21 | this.price = (json[keyPrice] != null && 22 | double.tryParse(json[keyPrice].toString()) != null) 23 | ? json[keyPrice] 24 | : 0.0; 25 | this.imageUrl = (json[keyImage] != null) ? json[keyImage].toString() : ''; 26 | } 27 | 28 | factory Pizza.fromJsonOrNull(Map json) { 29 | Pizza pizza = Pizza(); 30 | pizza.id = (json[keyId] != null) ? int.tryParse(json[keyId].toString()) : 0; 31 | pizza.pizzaName = (json[keyName] != null) ? json[keyName].toString() : ''; 32 | pizza.description = 33 | (json[keyDescription] != null) ? json[keyDescription].toString() : ''; 34 | pizza.price = (json[keyPrice] != null && 35 | double.tryParse(json[keyPrice].toString()) != null) 36 | ? json[keyPrice] 37 | : 0.0; 38 | pizza.imageUrl = (json[keyImage] != null) ? json[keyImage].toString() : ''; 39 | if (pizza.id == 0 || pizza.pizzaName.trim() == '') { 40 | return null; 41 | } 42 | return pizza; 43 | } 44 | 45 | Map toJson() { 46 | return { 47 | keyId: id, 48 | keyName: pizzaName, 49 | keyDescription: description, 50 | keyPrice: price, 51 | keyImage: imageUrl, 52 | }; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /chapter_08/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: chapter_8_http 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | http: ^0.13.1 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.2 31 | 32 | dev_dependencies: 33 | flutter_test: 34 | sdk: flutter 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | 47 | # To add assets to your application, add an assets section, like this: 48 | # assets: 49 | # - images/a_dot_burr.jpeg 50 | # - images/a_dot_ham.jpeg 51 | 52 | # An image asset can refer to one or more resolution-specific "variants", see 53 | # https://flutter.dev/assets-and-images/#resolution-aware. 54 | 55 | # For details regarding adding assets from package dependencies, see 56 | # https://flutter.dev/assets-and-images/#from-packages 57 | 58 | # To add custom fonts to your application, add a fonts section here, 59 | # in this "flutter" section. Each entry in this list should have a 60 | # "family" key with the font family name, and a "fonts" key with a 61 | # list giving the asset and other descriptors for the font. For 62 | # example: 63 | # fonts: 64 | # - family: Schyler 65 | # fonts: 66 | # - asset: fonts/Schyler-Regular.ttf 67 | # - asset: fonts/Schyler-Italic.ttf 68 | # style: italic 69 | # - family: Trajan Pro 70 | # fonts: 71 | # - asset: fonts/TrajanPro.ttf 72 | # - asset: fonts/TrajanPro_Bold.ttf 73 | # weight: 700 74 | # 75 | # For details regarding fonts from package dependencies, 76 | # see https://flutter.dev/custom-fonts/#from-packages 77 | -------------------------------------------------------------------------------- /chapter_09/chapter_9_a/lib/stream.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:async'; 3 | 4 | class ColorStream { 5 | Stream colorStream; 6 | Stream getColors() async* { 7 | final List colors = [ 8 | Colors.blueGrey, 9 | Colors.amber, 10 | Colors.deepPurple, 11 | Colors.lightBlue, 12 | Colors.teal 13 | ]; 14 | yield* Stream.periodic(Duration(seconds: 1), (int t) { 15 | int index = t % 5; 16 | return colors[index]; 17 | }); 18 | } 19 | } 20 | 21 | class NumberStream { 22 | StreamController controller = StreamController(); 23 | addNumberToSink(int newNumber) { 24 | controller.sink.add(newNumber); 25 | } 26 | 27 | addError() { 28 | controller.sink.addError('error'); 29 | } 30 | 31 | close() { 32 | controller.close(); 33 | } 34 | } -------------------------------------------------------------------------------- /chapter_09/chapter_9_b/lib/countdown_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | class TimerBLoC { 4 | int seconds = 60; 5 | StreamController _secondsStreamController = StreamController(); 6 | Stream get secondsStream => 7 | _secondsStreamController.stream.asBroadcastStream(); 8 | StreamSink get secondsSink => _secondsStreamController.sink; 9 | 10 | TimerBLoC( 11 | 12 | ); 13 | 14 | Future decreaseSeconds() async { 15 | await Future.delayed(const Duration(seconds: 1)); 16 | seconds--; 17 | secondsSink.add(seconds); 18 | } 19 | 20 | countDown() async { 21 | for (var i = seconds; i > 0; i--) { 22 | await decreaseSeconds(); 23 | returnSeconds(seconds); 24 | } 25 | } 26 | 27 | int returnSeconds(seconds) { 28 | return seconds; 29 | } 30 | 31 | void dispose() { 32 | _secondsStreamController.close(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /chapter_09/chapter_9_b/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'countdown_bloc.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'BLoC', 13 | theme: ThemeData( 14 | primarySwatch: Colors.deepPurple, 15 | visualDensity: VisualDensity.adaptivePlatformDensity, 16 | ), 17 | home: StreamHomePage(), 18 | ); 19 | } 20 | } 21 | 22 | class StreamHomePage extends StatefulWidget { 23 | @override 24 | _StreamHomePageState createState() => _StreamHomePageState(); 25 | } 26 | 27 | class _StreamHomePageState extends State { 28 | TimerBLoC timerBloc; 29 | int seconds; 30 | @override 31 | void initState() { 32 | timerBloc = TimerBLoC(); 33 | seconds = timerBloc.seconds; 34 | timerBloc.countDown(); 35 | super.initState(); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Scaffold( 41 | appBar: AppBar( 42 | title: Text('BLoC'), 43 | ), 44 | body: Container( 45 | child: StreamBuilder( 46 | stream: timerBloc.secondsStream, 47 | initialData: seconds, 48 | builder: (context, snapshot) { 49 | if (snapshot.hasError) { 50 | print('Error!'); 51 | } 52 | if (snapshot.hasData) { 53 | return Center( 54 | child: Text( 55 | snapshot.data.toString(), 56 | style: TextStyle(fontSize: 96), 57 | )); 58 | } else { 59 | return Center(); 60 | } 61 | }, 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /chapter_09/chapter_9_b/lib/stream.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class NumberStream { 4 | Stream getNumbers() async* { 5 | yield* Stream.periodic(Duration(seconds: 1), (int t) { 6 | Random random = Random(); 7 | int myNum = random.nextInt(10); 8 | return myNum; 9 | }); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chapter_09/chapter_9_b/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: chapter_9_b 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.2 31 | 32 | dev_dependencies: 33 | flutter_test: 34 | sdk: flutter 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | 47 | # To add assets to your application, add an assets section, like this: 48 | # assets: 49 | # - images/a_dot_burr.jpeg 50 | # - images/a_dot_ham.jpeg 51 | 52 | # An image asset can refer to one or more resolution-specific "variants", see 53 | # https://flutter.dev/assets-and-images/#resolution-aware. 54 | 55 | # For details regarding adding assets from package dependencies, see 56 | # https://flutter.dev/assets-and-images/#from-packages 57 | 58 | # To add custom fonts to your application, add a fonts section here, 59 | # in this "flutter" section. Each entry in this list should have a 60 | # "family" key with the font family name, and a "fonts" key with a 61 | # list giving the asset and other descriptors for the font. For 62 | # example: 63 | # fonts: 64 | # - family: Schyler 65 | # fonts: 66 | # - asset: fonts/Schyler-Regular.ttf 67 | # - asset: fonts/Schyler-Italic.ttf 68 | # style: italic 69 | # - family: Trajan Pro 70 | # fonts: 71 | # - asset: fonts/TrajanPro.ttf 72 | # - asset: fonts/TrajanPro_Bold.ttf 73 | # weight: 700 74 | # 75 | # For details regarding fonts from package dependencies, 76 | # see https://flutter.dev/custom-fonts/#from-packages 77 | -------------------------------------------------------------------------------- /chapter_10/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:area/area.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Packages Demo', 13 | home: PackageScreen(), 14 | ); 15 | } 16 | } 17 | 18 | class PackageScreen extends StatefulWidget { 19 | @override 20 | _PackageScreenState createState() => _PackageScreenState(); 21 | } 22 | 23 | class _PackageScreenState extends State { 24 | final TextEditingController txtHeight = TextEditingController(); 25 | final TextEditingController txtWidth = TextEditingController(); 26 | String result = ''; 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | appBar: AppBar( 31 | title: Text('Package App'), 32 | ), 33 | body: Column( 34 | children: [ 35 | AppTextField(txtWidth, 'Width'), 36 | AppTextField(txtHeight, 'Height'), 37 | Padding( 38 | padding: EdgeInsets.all(24), 39 | ), 40 | ElevatedButton( 41 | child: Text('Calculate Area'), 42 | onPressed: () { 43 | double width = double.tryParse(txtWidth.text); 44 | double height = double.tryParse(txtHeight.text); 45 | String res = calculateAreaRect(width, height); 46 | setState(() { 47 | result = res; 48 | }); 49 | }), 50 | Padding( 51 | padding: EdgeInsets.all(24), 52 | ), 53 | Text(result), 54 | ], 55 | ), 56 | ); 57 | } 58 | } 59 | 60 | class AppTextField extends StatelessWidget { 61 | final TextEditingController controller; 62 | final String label; 63 | AppTextField(this.controller, this.label); 64 | @override 65 | Widget build(BuildContext context) { 66 | return Padding( 67 | padding: EdgeInsets.all(24), 68 | child: TextField( 69 | controller: controller, 70 | decoration: InputDecoration(hintText: label), 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /chapter_11/lib/animatedlist.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AnimatedListScreen extends StatefulWidget { 4 | @override 5 | _AnimatedListScreenState createState() => _AnimatedListScreenState(); 6 | } 7 | 8 | class _AnimatedListScreenState extends State { 9 | final GlobalKey listKey = GlobalKey(); 10 | final List _items = [1, 2, 3, 4, 5]; 11 | int counter = 0; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text('Animated List'), 18 | ), 19 | floatingActionButton: FloatingActionButton( 20 | child: Icon(Icons.add), 21 | onPressed: () { 22 | insertPizza(); 23 | }, 24 | ), 25 | body: AnimatedList( 26 | key: listKey, 27 | initialItemCount: _items.length, 28 | itemBuilder: (BuildContext context, int index, Animation animation) { 29 | return fadeListTile(context, index, animation); 30 | }, 31 | )); 32 | } 33 | 34 | fadeListTile(BuildContext context, int index, Animation animation) { 35 | int item = _items[index]; 36 | return FadeTransition( 37 | opacity: Tween(begin: 0.0, end: 1.0).animate(animation), 38 | child: Card( 39 | child: ListTile( 40 | title: Text('Pizza ' + item.toString()), 41 | onTap: () { 42 | removePizza(index); 43 | }, 44 | ), 45 | ), 46 | ); 47 | } 48 | 49 | removePizza(int index) { 50 | int animationIndex = index; 51 | if (index == _items.length - 1) animationIndex--; 52 | listKey.currentState.removeItem( 53 | index, 54 | (context, animation) => fadeListTile(context, animationIndex, animation), 55 | duration: Duration(seconds: 1), 56 | ); 57 | _items.removeAt(index); 58 | } 59 | 60 | insertPizza() { 61 | listKey.currentState.insertItem( 62 | _items.length, 63 | duration: Duration(seconds: 1), 64 | ); 65 | _items.add(++counter); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /chapter_11/lib/detail_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DetailScreen extends StatelessWidget { 4 | final int index; 5 | DetailScreen(this.index); 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | appBar: AppBar( 10 | title: Text('Detail Screen'), 11 | ), 12 | body: Column( 13 | children: [ 14 | Expanded( 15 | flex: 1, 16 | child: Container( 17 | width: double.infinity, 18 | decoration: BoxDecoration(color: Colors.amber), 19 | child: Hero( 20 | tag: 'cup$index', 21 | child: Icon( 22 | Icons.free_breakfast, 23 | size: 96, 24 | ), 25 | ), 26 | ), 27 | ), 28 | Expanded( 29 | flex: 3, 30 | child: Container(), 31 | ) 32 | ], 33 | )); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /chapter_11/lib/dismissible.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:animations/animations.dart'; 3 | 4 | class DismissibleScreen extends StatefulWidget { 5 | @override 6 | _DismissibleScreenState createState() => _DismissibleScreenState(); 7 | } 8 | 9 | class _DismissibleScreenState extends State { 10 | final List sweets = [ 11 | 'Petit Four', 12 | 'Cupcake', 13 | 'Donut', 14 | 'Éclair', 15 | 'Froyo', 16 | 'Gingerbread ', 17 | 'Honeycomb ', 18 | 'Ice Cream Sandwich', 19 | 'Jelly Bean', 20 | 'KitKat' 21 | ]; 22 | @override 23 | Widget build(BuildContext context) { 24 | return Scaffold( 25 | appBar: AppBar( 26 | title: Text('Dismissible Example'), 27 | ), 28 | body: ListView.builder( 29 | itemCount: sweets.length, 30 | itemBuilder: (context, index) { 31 | return OpenContainer( 32 | transitionDuration: Duration(seconds: 3), 33 | transitionType: ContainerTransitionType.fade, 34 | openBuilder: (context, closeContainer) { 35 | return Scaffold( 36 | appBar: AppBar( 37 | title: Text(sweets[index]), 38 | ), 39 | body: Center( 40 | child: Column( 41 | children: [ 42 | Container( 43 | width: 200, 44 | height: 200, 45 | child: Icon( 46 | Icons.cake, 47 | size: 200, 48 | color: Colors.orange, 49 | ), 50 | ), 51 | Text(sweets[index]) 52 | ], 53 | ), 54 | ), 55 | ); 56 | }, 57 | closedBuilder: (context, openContainer) { 58 | return Dismissible( 59 | key: Key(sweets[index]), 60 | child: ListTile( 61 | title: Text(sweets[index]), 62 | trailing: Icon(Icons.cake), 63 | onTap: () { 64 | openContainer(); 65 | }, 66 | ), 67 | onDismissed: (direction) { 68 | sweets.removeAt(index); 69 | }, 70 | ); 71 | }, 72 | ); 73 | })); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /chapter_11/lib/fade_transition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FadeTransitionScreen extends StatefulWidget { 4 | @override 5 | _FadeTransitionScreenState createState() => _FadeTransitionScreenState(); 6 | } 7 | 8 | class _FadeTransitionScreenState extends State 9 | with SingleTickerProviderStateMixin { 10 | AnimationController controller; 11 | Animation animation; 12 | 13 | @override 14 | void initState() { 15 | controller = 16 | AnimationController(vsync: this, duration: Duration(seconds: 3)); 17 | animation = Tween(begin: 0.0, end: 1.0).animate(controller); 18 | super.initState(); 19 | } 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | controller.forward(); 24 | return Scaffold( 25 | appBar: AppBar( 26 | title: Text('Fade Transition Recipe'), 27 | ), 28 | body: Center( 29 | child: FadeTransition( 30 | opacity: animation, 31 | child: Container( 32 | width: 200, 33 | height: 200, 34 | color: Colors.purple, 35 | ), 36 | ), 37 | ), 38 | ); 39 | } 40 | 41 | @override 42 | void dispose() { 43 | controller.dispose(); 44 | super.dispose(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /chapter_11/lib/list_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import './detail_screen.dart'; 3 | 4 | class ListScreen extends StatelessWidget { 5 | final List drinks = ['Coffee', 'Tea', 'Cappuccino', 'Espresso']; 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | appBar: AppBar( 10 | title: Text('Hero Animation'), 11 | ), 12 | body: ListView.builder( 13 | itemCount: drinks.length, 14 | itemBuilder: (BuildContext context, int index) { 15 | return ListTile( 16 | leading: 17 | Hero(tag: 'cup$index', child: Icon(Icons.free_breakfast)), 18 | title: Text(drinks[index]), 19 | onTap: () { 20 | Navigator.push( 21 | context, 22 | MaterialPageRoute( 23 | builder: (context) => DetailScreen(index))); 24 | }, 25 | ); 26 | }), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /chapter_11/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:cookbook_ch_11/dismissible.dart'; 2 | import 'package:cookbook_ch_11/list_screen.dart'; 3 | import 'package:flutter/material.dart'; 4 | import './shape_animation.dart'; 5 | import 'animatedlist.dart'; 6 | import 'fade_transition.dart'; 7 | import 'my_animation.dart'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | title: 'Animations Demo', 18 | theme: ThemeData( 19 | primarySwatch: Colors.blue, 20 | ), 21 | home: DismissibleScreen(), 22 | ); 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /chapter_11/lib/my_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MyAnimation extends StatefulWidget { 4 | @override 5 | _MyAnimationState createState() => _MyAnimationState(); 6 | } 7 | 8 | class _MyAnimationState extends State { 9 | final List colors = [ 10 | Colors.red, 11 | Colors.green, 12 | Colors.yellow, 13 | Colors.blue, 14 | Colors.orange 15 | ]; 16 | final List sizes = [100, 125, 150, 175, 200]; 17 | final List tops = [0, 50, 100, 150, 200]; 18 | int iteration = 0; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Scaffold( 23 | appBar: AppBar( 24 | title: Text('Animated Container'), 25 | actions: [ 26 | IconButton( 27 | icon: Icon(Icons.run_circle), 28 | onPressed: () { 29 | iteration < colors.length - 1 ? iteration++ : iteration = 0; 30 | setState(() { 31 | iteration = iteration; 32 | }); 33 | }, 34 | ) 35 | ], 36 | ), 37 | body: Center( 38 | child: AnimatedContainer( 39 | duration: Duration(seconds: 1), 40 | color: colors[iteration], 41 | width: sizes[iteration], 42 | height: sizes[iteration], 43 | margin: EdgeInsets.only(top: tops[iteration]), 44 | ))); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /chapter_11/lib/shape_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ShapeAnimation extends StatefulWidget { 4 | @override 5 | _ShapeAnimationState createState() => _ShapeAnimationState(); 6 | } 7 | 8 | class _ShapeAnimationState extends State 9 | with SingleTickerProviderStateMixin { 10 | AnimationController controller; 11 | Animation animation; 12 | double posTop = 0; 13 | double posLeft = 0; 14 | Animation animationTop; 15 | Animation animationLeft; 16 | double maxTop = 0; 17 | double maxLeft = 0; 18 | final int ballSize = 100; 19 | 20 | @override 21 | void initState() { 22 | controller = AnimationController( 23 | duration: const Duration(seconds: 3), 24 | vsync: this, 25 | )..repeat(reverse: true); 26 | // animationLeft = Tween(begin: 0, end: 200).animate(controller); 27 | // animationTop = Tween(begin: 0, end: 400).animate(controller) 28 | // ..addListener(() { 29 | // moveBall(); 30 | // }); 31 | 32 | animation = CurvedAnimation( 33 | parent: controller, 34 | curve: Curves.easeInOut, 35 | ); 36 | 37 | animation 38 | ..addListener(() { 39 | moveBall(); 40 | }); 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | return Scaffold( 47 | appBar: AppBar( 48 | title: Text('Animation Controller'), 49 | // actions: [ 50 | // IconButton( 51 | // onPressed: () { 52 | // controller.reset(); 53 | // controller.forward(); 54 | // }, 55 | // icon: Icon(Icons.run_circle), 56 | // ) 57 | // ], 58 | ), 59 | body: SafeArea(child: LayoutBuilder( 60 | builder: (BuildContext context, BoxConstraints constraints) { 61 | maxLeft = constraints.maxWidth - ballSize; 62 | maxTop = constraints.maxHeight - ballSize; 63 | return Stack(children: [ 64 | AnimatedBuilder( 65 | animation: controller, 66 | child: Positioned(left: posLeft, top: posTop, child: Ball()), 67 | builder: (BuildContext context, Widget child) { 68 | moveBall(); 69 | return Positioned( 70 | left: posLeft, top: posTop, child: Ball()); 71 | }) 72 | ]); 73 | }, 74 | ))); 75 | } 76 | 77 | void moveBall() { 78 | posTop = animation.value * maxTop ; 79 | posLeft = animation.value * maxLeft ; 80 | } 81 | } 82 | 83 | class Ball extends StatelessWidget { 84 | @override 85 | Widget build(BuildContext context) { 86 | return Container( 87 | width: 100, 88 | height: 100, 89 | decoration: BoxDecoration(color: Colors.orange, shape: BoxShape.circle), 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /chapter_12/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: lines_longer_than_80_chars 6 | 7 | import 'package:cloud_firestore_web/cloud_firestore_web.dart'; 8 | import 'package:firebase_analytics_web/firebase_analytics_web.dart'; 9 | import 'package:firebase_auth_web/firebase_auth_web.dart'; 10 | import 'package:firebase_core_web/firebase_core_web.dart'; 11 | import 'package:firebase_storage_web/firebase_storage_web.dart'; 12 | import 'package:google_sign_in_web/google_sign_in_web.dart'; 13 | import 'package:image_picker_for_web/image_picker_for_web.dart'; 14 | 15 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 16 | 17 | // ignore: public_member_api_docs 18 | void registerPlugins(Registrar registrar) { 19 | FirebaseFirestoreWeb.registerWith(registrar); 20 | FirebaseAnalyticsWeb.registerWith(registrar); 21 | FirebaseAuthWeb.registerWith(registrar); 22 | FirebaseCoreWeb.registerWith(registrar); 23 | FirebaseStorageWeb.registerWith(registrar); 24 | GoogleSignInPlugin.registerWith(registrar); 25 | ImagePickerPlugin.registerWith(registrar); 26 | registrar.registerMessageHandler(); 27 | } 28 | -------------------------------------------------------------------------------- /chapter_12/lib/happy_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:firebase_analytics/firebase_analytics.dart'; 3 | 4 | class HappyScreen extends StatefulWidget { 5 | @override 6 | _HappyScreenState createState() => _HappyScreenState(); 7 | } 8 | 9 | class _HappyScreenState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text('Happy Happy!'), 15 | ), 16 | body: Center( 17 | child: ElevatedButton( 18 | child: Text('I\'m happy!'), 19 | onPressed: () { 20 | FirebaseAnalytics().logEvent(name: 'Happy', parameters: null); 21 | }, 22 | ), 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter_12/lib/shared/firebase_authentication.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'dart:async'; 3 | import 'package:google_sign_in/google_sign_in.dart'; 4 | 5 | class FirebaseAuthentication { 6 | final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; 7 | final GoogleSignIn googleSignIn = GoogleSignIn(); 8 | 9 | Future createUser(String email, String password) async { 10 | try { 11 | UserCredential credential = await _firebaseAuth 12 | .createUserWithEmailAndPassword(email: email, password: password); 13 | return credential.user.uid; 14 | } on FirebaseAuthException { 15 | return null; 16 | } 17 | } 18 | 19 | Future login(String email, String password) async { 20 | try { 21 | UserCredential credential = await _firebaseAuth 22 | .signInWithEmailAndPassword(email: email, password: password); 23 | return credential.user.uid; 24 | } on FirebaseAuthException { 25 | return null; 26 | } 27 | } 28 | 29 | Future logout() async { 30 | try { 31 | _firebaseAuth.signOut(); 32 | return true; 33 | } on FirebaseAuthException { 34 | return false; 35 | } 36 | } 37 | 38 | Future loginWithGoogle() async { 39 | final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); 40 | final GoogleSignInAuthentication googleSignInAuthentication = 41 | await googleSignInAccount.authentication; 42 | final AuthCredential authCredential = GoogleAuthProvider.credential( 43 | accessToken: googleSignInAuthentication.accessToken, 44 | idToken: googleSignInAuthentication.idToken, 45 | ); 46 | final UserCredential authResult = 47 | await _firebaseAuth.signInWithCredential(authCredential); 48 | final User user = authResult.user; 49 | if (user != null) { 50 | return '$user'; 51 | } 52 | return null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /chapter_12/lib/upload_file.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:io'; 3 | import 'package:path/path.dart'; 4 | import 'package:image_picker/image_picker.dart'; 5 | import 'package:firebase_storage/firebase_storage.dart'; 6 | 7 | class UploadFileScreen extends StatefulWidget { 8 | @override 9 | _UploadFileScreenState createState() => _UploadFileScreenState(); 10 | } 11 | 12 | class _UploadFileScreenState extends State { 13 | File _image; 14 | String _message = ''; 15 | final picker = ImagePicker(); 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar(title: Text('Upload To FireStore')), 20 | body: Container( 21 | padding: EdgeInsets.all(24), 22 | child: Column( 23 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 24 | crossAxisAlignment: CrossAxisAlignment.stretch, 25 | children: [ 26 | ElevatedButton( 27 | child: Text('Choose Image'), 28 | onPressed: () {getImage();}, 29 | ), 30 | (_image == null) 31 | ? Container(height: 200) 32 | : Container(height: 200, child: Image.file(_image)), 33 | ElevatedButton( 34 | child: Text('Upload Image'), 35 | onPressed: () {uploadImage();}, 36 | ), 37 | Text(_message), 38 | ], 39 | ), 40 | ), 41 | ); 42 | } 43 | 44 | Future getImage() async { 45 | final pickedFile = await picker.getImage(source: ImageSource.gallery); 46 | setState(() { 47 | if (pickedFile != null) { 48 | _image = File(pickedFile.path); 49 | } else { 50 | print('No image selected.'); 51 | } 52 | }); 53 | } 54 | 55 | Future uploadImage() async { 56 | if (_image != null) { 57 | String fileName = basename(_image.path); 58 | FirebaseStorage storage = FirebaseStorage.instance; 59 | Reference ref = storage.ref(fileName); 60 | setState(() { 61 | _message = 'Uploading file. Please wait...'; 62 | }); 63 | ref.putFile(_image).then((TaskSnapshot result) { 64 | if (result.state == TaskState.success) { 65 | setState(() { 66 | _message = 'File Uploaded Successfully'; 67 | }); 68 | } else { 69 | setState(() { 70 | _message = 'Error Uploading File'; 71 | }); 72 | } 73 | }); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /chapter_13/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: lines_longer_than_80_chars 6 | 7 | import 'package:firebase_core_web/firebase_core_web.dart'; 8 | 9 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 10 | 11 | // ignore: public_member_api_docs 12 | void registerPlugins(Registrar registrar) { 13 | FirebaseCoreWeb.registerWith(registrar); 14 | registrar.registerMessageHandler(); 15 | } 16 | -------------------------------------------------------------------------------- /chapter_13/lib/language.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'ml.dart'; 3 | import 'result.dart'; 4 | 5 | class LanguageScreen extends StatefulWidget { 6 | @override 7 | _LanguageScreenState createState() => _LanguageScreenState(); 8 | } 9 | 10 | class _LanguageScreenState extends State { 11 | final TextEditingController txtLanguage = TextEditingController(); 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text('Language Detection'), 17 | ), 18 | body: Container( 19 | padding: EdgeInsets.all(32), 20 | child: Column( 21 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 22 | children: [ 23 | TextField( 24 | controller: txtLanguage, 25 | maxLines: 5, 26 | decoration: InputDecoration( 27 | labelText: 'Enter some text in any language', 28 | ), 29 | ), 30 | Center( 31 | child: ElevatedButton( 32 | child: Text('Detect Language'), 33 | onPressed: () { 34 | MLHelper helper = MLHelper(); 35 | helper.identifyLanguage(txtLanguage.text).then((result) { 36 | Navigator.push( 37 | context, 38 | MaterialPageRoute( 39 | builder: (context) => ResultScreen(result))); 40 | }); 41 | }, 42 | )) 43 | ], 44 | ), 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chapter_13/lib/main.dart: -------------------------------------------------------------------------------- 1 | import './camera.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Firebase Machine Learning', 13 | theme: ThemeData( 14 | primarySwatch: Colors.deepOrange, 15 | ), 16 | home: CameraScreen(), 17 | ); 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /chapter_13/lib/picture.dart: -------------------------------------------------------------------------------- 1 | import 'package:camera/camera.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:io'; 4 | 5 | class PictureScreen extends StatefulWidget { 6 | final XFile picture; 7 | PictureScreen(this.picture); 8 | @override 9 | _PictureScreenState createState() => _PictureScreenState(); 10 | } 11 | 12 | class _PictureScreenState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | double deviceHeight = MediaQuery.of(context).size.height; 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('Picture'), 19 | ), 20 | body: Column( 21 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 22 | children: [ 23 | Text(widget.picture.path), 24 | Container( 25 | height: deviceHeight / 1.5, 26 | child: Image.file(File(widget.picture.path))), 27 | Row( 28 | children: [ 29 | ElevatedButton( 30 | child: Text('Text Recognition'), 31 | onPressed: () {}, 32 | ) 33 | ], 34 | ) 35 | ], 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /chapter_13/lib/result.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ResultScreen extends StatefulWidget { 4 | final String result; 5 | ResultScreen(this.result); 6 | @override 7 | _ResultScreenState createState() => _ResultScreenState(); 8 | } 9 | 10 | class _ResultScreenState extends State { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | appBar: AppBar( 15 | title: Text('Result'), 16 | ), 17 | body: Container( 18 | child: Padding( 19 | padding: EdgeInsets.all(24), 20 | child: SelectableText(widget.result, 21 | showCursor: true, 22 | cursorColor: Theme.of(context).accentColor, 23 | cursorWidth: 5, 24 | toolbarOptions: ToolbarOptions(copy: true, selectAll: true), 25 | scrollPhysics: ClampingScrollPhysics(), 26 | onTap: (){}, 27 | )), 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /chapter_15/lib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flutter-Cookbook/4c12a740f0103bd6ba68ed28f3ca36fd59d7ccd3/chapter_15/lib/.DS_Store -------------------------------------------------------------------------------- /chapter_15/lib/data/http_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | import 'dart:convert'; 3 | import 'dart:async'; 4 | import 'package:http/http.dart'; 5 | import '../models/book.dart'; 6 | 7 | class HttpHelper { 8 | final String authority = 'www.googleapis.com'; 9 | final String path = '/books/v1/volumes'; 10 | 11 | 12 | Future> getBooks(String query) async { 13 | Map params = {'q':query, 'maxResults': '40', }; 14 | Uri uri = Uri.https(authority, path, params); 15 | Response result = await http.get(uri); 16 | if (result.statusCode == 200) { 17 | final jsonResponse = json.decode(result.body); 18 | final booksMap = jsonResponse['items']; 19 | List books = booksMap.map((i) => Book.fromJson(i)).toList(); 20 | return books; 21 | } else { 22 | return []; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /chapter_15/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'screens/book_list_screen.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Flutter Demo', 13 | theme: ThemeData( 14 | primarySwatch: Colors.blue, 15 | ), 16 | home: BookListScreen(), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter_15/lib/models/book.dart: -------------------------------------------------------------------------------- 1 | class Book { 2 | String id; 3 | String title; 4 | String authors; 5 | String thumbnail; 6 | String description; 7 | 8 | Book(this.id, this.title, this.authors, this.thumbnail, this.description); 9 | 10 | factory Book.fromJson(Map parsedJson) { 11 | final String id = parsedJson['id']; 12 | final String title = parsedJson['volumeInfo']['title']; 13 | String image = parsedJson['volumeInfo']['imageLinks'] == null 14 | ? '' 15 | : parsedJson['volumeInfo']['imageLinks']['thumbnail']; 16 | image.replaceAll('http://', 'https://'); 17 | final String authors = (parsedJson['volumeInfo']['authors'] == null) ? '' : parsedJson['volumeInfo']['authors'].toString(); 18 | final String description = (parsedJson['volumeInfo']['description'] == null) 19 | ? '' 20 | : parsedJson['volumeInfo']['description']; 21 | return Book(id, title, authors, image, description); 22 | } 23 | } 24 | --------------------------------------------------------------------------------