Урок 1.00:01:51
Course Introduction
Урок 2.00:02:02
Course Content
Урок 3.00:03:25
App Overview
Урок 4.00:02:43
Making the most of this course
Урок 5.00:03:14
What is Flutter
Урок 6.00:02:26
The Dart Language
Урок 7.00:00:49
Introduction to Dartpad
Урок 8.00:01:43
A simple program
Урок 9.00:01:44
Variable declaration and initialization
Урок 10.00:03:04
String interpolation
Урок 11.00:03:14
Type inference with var
Урок 12.00:01:55
Var and final
Урок 13.00:01:54
The dynamic keyword
Урок 14.00:04:19
Introduction to functions
Урок 15.00:02:06
Function return types
Урок 16.00:02:32
Optional parameters, nullability and default values
Урок 17.00:01:59
Named parameters
Урок 18.00:01:52
The arrow operator
Урок 19.00:02:02
Introduction to classes
Урок 20.00:03:06
Class constructors
Урок 21.00:02:15
Instance methods
Урок 22.00:02:57
Inheritance
Урок 23.00:02:00
The super constructor
Урок 24.00:01:49
The base Object class and the toString method
Урок 25.00:05:26
Overriding the toString method
Урок 26.00:03:22
Abstract classes
Урок 27.00:02:34
More on abstract classes
Урок 28.00:01:56
Using abstract classes with functions
Урок 29.00:02:40
Computed properties
Урок 30.00:04:38
Mixins
Урок 31.00:03:44
Introduction to lists
Урок 32.00:03:32
Introduction to maps
Урок 33.00:04:54
Generics and type annotations
Урок 34.00:03:52
If and else statements
Урок 35.00:02:26
The ternary operator
Урок 36.00:03:14
The while loop
Урок 37.00:02:00
The for loop
Урок 38.00:04:13
Closures and the fold method
Урок 39.00:02:46
Enumerations
Урок 40.00:02:50
Switch statements
Урок 41.00:01:12
Wrap-up
Урок 42.00:02:40
Flutter setup on macOS
Урок 43.00:04:27
Setting the PATH variable
Урок 44.00:00:51
Flutter doctor
Урок 45.00:02:18
Xcode and iOS simulator setup
Урок 46.00:05:55
Installing Android Studio
Урок 47.00:02:21
Installing the Android emulator
Урок 48.00:05:22
Running Flutter from the command line
Урок 49.00:03:36
Flutter setup on Android Studio
Урок 50.00:03:12
Installing Visual Studio Code
Урок 51.00:01:28
Flutter setup on Windows
Урок 52.00:02:10
Updating the path variable
Урок 53.00:00:55
Flutter doctor
Урок 54.00:04:28
Installing Android Studio
Урок 55.00:03:19
Installing the Android emulator
Урок 56.00:02:58
Running Flutter from the command line
Урок 57.00:04:20
Flutter setup on Android Studio
Урок 58.00:02:54
Installing Visual Studio Code
Урок 59.00:03:29
Creating a Flutter project with Android Studio
Урок 60.00:02:41
A tour of the project folders
Урок 61.00:02:10
Running the Android emulator and iOS simulator
Урок 62.00:01:09
Overview of the Flutter counter app
Урок 63.00:04:07
Hot reload and hot restart
Урок 64.00:02:23
Introduction to widgets
Урок 65.00:01:52
The MaterialApp widget
Урок 66.00:02:38
The Scaffold widget
Урок 67.00:03:26
The Flutter widget tree
Урок 68.00:02:44
Stateless and stateful widgets
Урок 69.00:02:11
Updating the counter with setState
Урок 70.00:01:11
Wrap up
Урок 71.00:01:43
Overview of the Time tracker app
Урок 72.00:00:55
Switching between apps
Урок 73.00:04:08
Writing the root widget of the app
Урок 74.00:02:51
Adding the MaterialApp
Урок 75.00:02:20
Adding some folders to our project
Урок 76.00:03:36
Adding a sign-in page
Урок 77.00:02:13
The ThemeData class
Урок 78.00:02:39
The AppBar widget
Урок 79.00:01:28
Preview of the SignInPage layout
Урок 80.00:03:18
Adding a Column layout
Урок 81.00:03:56
The CrossAxisAlignment property
Урок 82.00:04:54
Code formatting with dartfmt
Урок 83.00:03:40
Adding some boxes and extracting code into a method
Урок 84.00:03:26
Private methods
Урок 85.00:04:34
Adding some padding
Урок 86.00:01:15
The MainAxisAlignment property
Урок 87.00:03:13
Text, TextStyle and FontWeight
Урок 88.00:01:50
Introduction to buttons
Урок 89.00:03:30
Adding the first button
Урок 90.00:04:15
Button callbacks explained
Урок 91.00:03:10
Customising button colors
Урок 92.00:03:09
MaterialColor explained
Урок 93.00:02:17
Changing button shapes
Урок 94.00:01:25
Making code reusable
Урок 95.00:06:40
Creating a reusable custom RaisedButton
Урок 96.00:04:14
Creating a reusable SignInButton
Урок 97.00:02:23
Setting default values
Урок 98.00:03:56
Making the button height configurable
Урок 99.00:04:37
Adding the remaining buttons
Урок 100.00:01:18
Adding logos: introduction
Урок 101.00:04:03
Updating the pubspec.yaml file
Урок 102.00:01:54
Image variants
Урок 103.00:03:34
Adding an image inside a button
Урок 104.00:04:28
Arranging widgets horizontally in a Row
Урок 105.00:02:40
The Opacity widget
Урок 106.00:05:59
Creating a custom SocialSignInButton
Урок 107.00:05:04
The @required annotation
Урок 108.00:09:03
Using assertions for better widget API design
Урок 109.00:03:57
Local and remote authentication
Урок 110.00:01:34
Introduction to Firebase
Урок 111.00:02:04
Creating a Firebase project
Урок 112.00:08:59
Configuring Firebase for Android
Урок 113.00:07:23
Configuring Firebase for iOS
Урок 114.00:03:23
Installing the firebase_core and firebase_auth packages
Урок 115.00:03:09
Initializing the Firebase App
Урок 116.00:01:26
Running on iOS and updating Cocoapods
Урок 117.00:02:01
Futures, async and await
Урок 118.00:04:16
Signing in anonymously with Firebase
Урок 119.00:03:07
The FirebaseAuth singleton and private constructors
Урок 120.00:01:26
Explaining the short-hand syntax for callbacks
Урок 121.00:02:44
Error handling with try/catch
Урок 122.00:03:10
Preview of the sign-in and sign-out flow
Урок 123.00:02:22
Creating a landing page widget
Урок 124.00:01:44
Adding a Firebase User to the LandingPage
Урок 125.00:02:55
Adding a callback to the SignInPage
Урок 126.00:03:06
Hooking up the onSignIn callback
Урок 127.00:04:03
Creating the home page
Урок 128.00:02:47
Adding the sign-out functionality
Урок 129.00:02:35
Hooking up the onSignOut callback
Урок 130.00:02:12
Retrieving the current user when the app starts
Урок 131.00:05:36
Explaining global access and scoped access
Урок 132.00:02:39
Creating the Auth class
Урок 133.00:03:04
The abstract AuthBase class
Урок 134.00:04:37
Using the Auth class
Урок 135.00:04:39
Lifting state up and its drawbacks
Урок 136.00:02:31
State Management & App Architecture
Урок 137.00:02:44
Introduction to Streams
Урок 138.00:04:02
Streams in practice with DartPad
Урок 139.00:04:52
Handling errors and closing streams
Урок 140.00:02:20
The authStateChanges stream
Урок 141.00:02:37
Listening to the authStateChanges stream
Урок 142.00:04:34
Adding the StreamBuilder code
Урок 143.00:03:09
More on StreamBuilder
Урок 144.00:02:42
Refactoring the sign-in flows
Урок 145.00:02:58
Wrap-up on Streams and StreamBuilder
Урок 146.00:02:00
Overview of the Firebase sign-in methods
Урок 147.00:02:30
Enabling support for Google Sign In
Урок 148.00:05:15
Adding Google Sign-In to the Auth class
Урок 149.00:01:35
Hooking up Google Sign-In to our button
Урок 150.00:03:49
Configuring Google Sign-In on iOS
Урок 151.00:02:51
Google Sign-In flow explained
Урок 152.00:03:02
Supporting Google Sign Out
Урок 153.00:02:57
Testing Google Sign-In on Android
Урок 154.00:00:47
Viewing registered users on the Firebase console
Урок 155.00:07:33
Registering a Facebook App
Урок 156.00:02:29
Enabling Facebook Sign-In on Firebase
Урок 157.00:01:24
Installing the Facebook login package
Урок 158.00:01:38
Enabling MultiDex support on Android
Урок 159.00:04:36
Adding the Facebook Sign-In code
Урок 160.00:03:36
Testing Facebook Sign-In on Android
Урок 161.00:04:40
Facebook iOS setup in Xcode
Урок 162.00:02:11
Testing Facebook Sign-In on iOS
Урок 163.00:02:57
Accessing the user's data and privacy considerations
Урок 164.00:02:21
Preview of the email & password sign-in page
Урок 165.00:02:00
Creating the email & password sign-in page
Урок 166.00:01:49
Passing the BuildContext across methods
Урок 167.00:05:21
Introduction to navigation
Урок 168.00:02:04
Adding a Card widget
Урок 169.00:05:18
Adding the email and password text fields
Урок 170.00:02:22
Adding the submit buttons
Урок 171.00:03:32
Creating a FormSubmitButton widget
Урок 172.00:05:24
Adding a TextEditingController
Урок 173.00:06:22
Toggling the form type
Урок 174.00:04:15
Adding the email & password authentication code
Урок 175.00:03:00
Implementing the submit method
Урок 176.00:02:56
Testing email & password sign-in
Урок 177.00:03:33
Customising the email and password text fields
Урок 178.00:04:48
Using FocusNode and FocusScope
Урок 179.00:05:31
Disabling the submit button on empty email or password
Урок 180.00:02:29
Adding a StringValidator class
Урок 181.00:02:51
Adding an email and password validation mixin
Урок 182.00:03:17
Showing an error text when the email or password are invalid
Урок 183.00:04:46
Tweaking form submission
Урок 184.00:02:52
Simulating a slow network with a delay
Урок 185.00:03:36
Adding a loading state to our form
Урок 186.00:02:15
Updating the email focus logic
Урок 187.00:03:37
Fixing the vertical overflow on small screens
Урок 188.00:04:42
Wrap-up
Урок 189.00:01:19
Introduction to dialogs
Урок 190.00:02:50
Showing a dialog
Урок 191.00:02:15
Dismissing dialogs
Урок 192.00:04:03
Platform-aware widgets on iOS, Android & more
Урок 193.00:04:48
Adding a reusable showAlertDialog function
Урок 194.00:04:21
Adding a sign-out confirmation dialog
Урок 195.00:02:01
Dialog differences on Android and iOS
Урок 196.00:03:36
Introduction to InheritedWidget
Урок 197.00:05:42
Creating an AuthProvider
Урок 198.00:06:23
Accessing the Auth object via the AuthProvider
Урок 199.00:01:42
Adding the provider package
Урок 200.00:04:56
Using the Provider class
Урок 201.00:04:09
Wrap-up about scoped access
Урок 202.00:01:09
Module Introduction
Урок 203.00:02:40
Creating better user-facing errors with FirebaseAuthException
Урок 204.00:03:03
Creating a custom exception alert dialog
Урок 205.00:03:16
Showing error alerts in the SignInPage
Урок 206.00:01:12
Adding a loading state: overview
Урок 207.00:02:33
Adding a loading state to the SignInPage
Урок 208.00:03:36
Using the loading state in the SignInPage
Урок 209.00:02:58
The dispose method
Урок 210.00:04:50
Introduction to state management with BLoCs
Урок 211.00:01:41
The application layers
Урок 212.00:04:53
BLoCs, sinks, streams, and asynchronous code
Урок 213.00:02:51
Introduction to the SignInBloc
Урок 214.00:03:27
Implementing a simple BLoC
Урок 215.00:02:38
Adding a Bloc with Provider inside a static method
Урок 216.00:02:48
Adding the StreamBuilder code
Урок 217.00:02:57
Converting the SignInPage to a stateless widget
Урок 218.00:03:16
The difference between Provider.of and Consumer
Урок 219.00:01:04
Disposing BLoCs with Provider
Урок 220.00:05:48
Adding authentication code to the SignInBloc
Урок 221.00:02:14
Updating the SignInPage
Урок 222.00:02:56
Fixing the BLoC submit method
Урок 223.00:01:16
Summary on the BLoC basics
Урок 224.00:02:36
Introduction to the email sign-in flow with BLoC
Урок 225.00:02:49
Creating a model class for the EmailSignInForm
Урок 226.00:02:32
Creating the EmailSignInBloc with a StreamController
Урок 227.00:06:39
Updating the model
Урок 228.00:05:20
Adding the BLoC submit method
Урок 229.00:05:06
Setting up the EmailSignInFormBlocBased with Provider
Урок 230.00:07:18
Refactoring the EmailSignInFormBlocBased widget by removing the state variables
Урок 231.00:03:36
Moving the business logic to the BLoC class
Урок 232.00:06:32
Moving more business logic to the model class
Урок 233.00:03:00
The benefits of separation of concerns with BLoC
Урок 234.00:03:36
Using stateful widgets with TextEditingControllers
Урок 235.00:02:06
Considerations about performance
Урок 236.00:03:38
Blocs and Services in the widget tree
Урок 237.00:02:24
Recap on State Management
Урок 238.00:02:07
Introduction to ValueNotifier
Урок 239.00:04:51
Adding a ValueNotifier with ChangeNotifierProvider
Урок 240.00:03:24
Consumer and ChangeNotifierProvider explained
Урок 241.00:02:54
Differences between BLoC/streams and ValueNotifier/ChangeNotifierProvider
Урок 242.00:01:26
Introduction to ChangeNotifier
Урок 243.00:04:48
Adding the EmailSignInChangeModel class
Урок 244.00:02:43
Completing the EmailSignInChangeModel class
Урок 245.00:05:32
Implementing the email sign-in form with ChangeNotifier
Урок 246.00:03:23
Comparing ValueNotifier and ChangeNotifier
Урок 247.00:03:46
Wrap up on State Management
Урок 248.00:02:06
Wrap up on the Authentication Flows
Урок 249.00:02:38
Overview of the time tracker app
Урок 250.00:04:28
Database schema and SQL vs NoSQL
Урок 251.00:02:27
Introduction to Cloud Firestore
Урок 252.00:02:01
Documents and Collections
Урок 253.00:03:20
Getting started with Firestore
Урок 254.00:03:22
Designing a Database API with CRUD operations
Урок 255.00:03:22
Managing private user data with Cloud Firestore
Урок 256.00:01:50
Installing Cloud Firestore
Урок 257.00:02:31
Renaming the HomePage to JobsPage
Урок 258.00:03:02
Adding the Database class
Урок 259.00:01:31
Adding the Database Provider
Урок 260.00:02:18
Adding a FloatingActionButton
Урок 261.00:06:51
Writing data to Firestore
Урок 262.00:04:03
Defining a strongly-typed Job model class
Урок 263.00:02:51
Defining a common API path class
Урок 264.00:02:43
Adding a generic setData method
Урок 265.00:04:53
Adding security rules
Урок 266.00:02:46
Handling Firestore permissions errors
Урок 267.00:04:57
Reading data from Firestore
Урок 268.00:04:02
Reading and parsing Firestore data streams
Урок 269.00:04:09
Adding a StreamBuilder to show a list of jobs
Урок 270.00:04:52
Debugging the StreamBuilder code
Урок 271.00:02:08
Firestore as a realtime database
Урок 272.00:02:50
Adding a factory constructor to our model class
Урок 273.00:03:01
Adding a generic method to read Firestore streams
Урок 274.00:04:27
Adding a FirestoreService class
Урок 275.00:03:15
Wrap-up on Cloud Firestore
Урок 276.00:01:51
Introduction to Forms with Cloud Firestore
Урок 277.00:04:24
Adding a new job page
Урок 278.00:04:00
The Placeholder widget
Урок 279.00:03:41
Introduction to Form and TextFormField
Урок 280.00:08:04
Validating and saving Form data
Урок 281.00:04:42
Accessing the Database object with the correct BuildContext
Урок 282.00:04:54
Saving jobs with a unique document ID
Урок 283.00:01:40
Handling errors
Урок 284.00:03:04
Enforcing unique job names
Урок 285.00:01:27
Fixing the integer-parsing code
Урок 286.00:01:16
Editing existing jobs: overview
Урок 287.00:03:51
Adding a custom JobListTile
Урок 288.00:04:47
Repurposing the AddJobPage for editing jobs
Урок 289.00:02:50
Reading the documentID from Firestore
Урок 290.00:04:18
Completing the code for editing jobs
Урок 291.00:02:47
Wrap up on working with Forms
Урок 292.00:01:53
Intro and multiple states of UI
Урок 293.00:03:31
Adding an empty content widget
Урок 294.00:04:46
Adding a reusable list items builder
Урок 295.00:04:52
Using ListView.builder
Урок 296.00:02:50
Using ListView.separated
Урок 297.00:02:28
Deleting jobs from Firestore
Урок 298.00:06:30
Adding swipe to delete support
Урок 299.00:01:51
Working with entries: overview
Урок 300.00:04:19
Relational data & drawbacks of NoSQL databases
Урок 301.00:01:21
Getting ready to add new files
Урок 302.00:03:03
Adding the source files to the project
Урок 303.00:02:14
Connecting the new code and updating the Firestore rules
Урок 304.00:03:02
Fixing the EditJobPage navigation
Урок 305.00:02:29
Overview of the JobEntriesPage
Урок 306.00:05:26
Reading and writing entries with Firestore
Урок 307.00:02:05
The EntryListItem widget (using InkWell and Expanded)
Урок 308.00:02:31
Formatting dates and currencies with the Intl package
Урок 309.00:02:54
Dart as UI: Spreads and Collection-if
Урок 310.00:05:28
Using date pickers with stateful widgets
Урок 311.00:04:07
Date and time input with a custom UI and DateTimePicker
Урок 312.00:05:11
Updating the UI when a Job changes
Урок 313.00:01:25
Wrap up and CupertinoDatePicker
Урок 314.00:02:01
Introduction to bottom navigation
Урок 315.00:01:46
Multiple navigation stacks
Урок 316.00:03:57
Creating a HomePage with a selected tab
Урок 317.00:06:38
Adding a CupertinoTabScaffold
Урок 318.00:02:35
Testing the bottom navigation
Урок 319.00:04:37
Adding the widget builders
Урок 320.00:04:27
Replacing the FloatingActionButtons
Урок 321.00:02:09
Moving the logout button to the AccountPage
Урок 322.00:03:22
Presenting modal routes with the root navigator
Урок 323.00:01:01
The CupertinoPageRoute
Урок 324.00:05:36
Handling the Android back button with WillPopScope and navigator keys
Урок 325.00:01:44
Adding pop-to-root navigation
Урок 326.00:01:44
Wrap up on multiple navigators
Урок 327.00:02:53
Introduction to advanced stream operations
Урок 328.00:02:25
Introduction to RxDart
Урок 329.00:03:22
Observable.combineLatest and data transformations in the time tracker app
Урок 330.00:01:16
Adding the source code for the new entries page
Урок 331.00:04:03
Reviewing the UI code for the entries page
Урок 332.00:04:23
Using combineLatest in practice
Урок 333.00:04:09
Data manipulation in the EntriesBloc
Урок 334.00:01:41
Wrap up on Observables
Урок 335.00:03:03
Single subscription vs broadcast streams
Урок 336.00:01:59
PublishSubject, ReplaySubject, BehaviorSubject
Урок 337.00:03:35
Adding a BehaviorSubject to the EmailSignInBloc
Урок 338.00:02:28
Wrap up and notes about local and remote state management
Урок 339.00:00:49
Completing the time tracker app: overview
Урок 340.00:01:40
Accessing the User object in the AccountPage
Урок 341.00:04:44
Adding an Avatar image
Урок 342.00:03:18
Finishing the Avatar code
Урок 343.00:00:38
Wrapping up the time tracker app
Урок 344.00:02:07
Introduction to writing tests
Урок 345.00:02:32
Testing Flutter Apps
Урок 346.00:03:31
Writing the first unit test
Урок 347.00:01:32
Running tests
Урок 348.00:01:19
Checking and fixing errors in tests
Урок 349.00:02:54
Testing edge cases by writing and fixing failing tests
Урок 350.00:03:06
Grouping tests together
Урок 351.00:03:43
The setUp method and testing date formatting with locales
Урок 352.00:01:47
The test lifecycle methods
Урок 353.00:03:26
Completing the formatting tests
Урок 354.00:03:49
Testing model classes
Урок 355.00:04:58
hashCode and the == operator
Урок 356.00:04:55
Adding a toString() method, wrap up on unit tests
Урок 357.00:03:38
Introduction to widget tests
Урок 358.00:03:07
Finding widgets and matcher arguments
Урок 359.00:02:35
Testing widget callbacks
Урок 360.00:01:17
Working with Acceptance Criteria
Урок 361.00:02:06
Introduction to test mocks and mockito
Урок 362.00:04:29
Injecting mock objects with Provider
Урок 363.00:03:33
Verifying mock methods
Урок 364.00:06:19
Working with keys, entering text and the pump() method
Урок 365.00:02:53
Testing widget updates on state changes
Урок 366.00:02:17
Completing the email sign-in tests
Урок 367.00:02:31
Replacing Navigator.pop with a callback when the user signs in
Урок 368.00:02:13
Updating the tests to handle the form callback
Урок 369.00:05:42
Stubbing mock objects
Урок 370.00:02:23
Recap on the email sign in forms and stubbing mocks
Урок 371.00:02:56
Using widget tests with StreamBuilder
Урок 372.00:07:08
Using StreamController inside tests
Урок 373.00:05:17
Adding a Database builder to the Landing Page
Урок 374.00:02:46
Test setup for the SignInPage
Урок 375.00:02:40
Adding keys to custom widget classes
Урок 376.00:04:42
Testing navigation
Урок 377.00:01:55
The great thing about widget tests
Урок 378.00:07:08
Testing ValueNotifier models
Урок 379.00:03:37
Testing ChangeNotifier models
Урок 380.00:03:27
Testing BloCs
Урок 381.00:01:18
Comparing EmailSignInModel objects
Урок 382.00:08:01
Testing streams in Blocs
Урок 383.00:01:25
Wrap up on unit & widget tests
Урок 384.00:04:16
Conclusion and Next Steps