Dart and Flutter: The Complete Developer's Guide
Everything you need to know for building mobile apps with Flutter and Dart, including RxDart and Animations!
What you will learn?
- Build beautiful multi-screen apps with Flutter
- Understand the different approaches for loading and maintaining data in Flutter apps
- Create and publish open source projects using Dart
- Learn how to build offline-enabled apps with incredibly efficient data loading
- Comprehend the best method for reading the incredible amount of Flutter documentation
- Store long-term data on a user's physical device using SQLite
- Master streams and understand reactive programming to create Flutter apps
Your trainer
Stephen Grider
Stephen Grider has been building complex Javascript front ends for top corporations in the San Francisco Bay Area. With an innate ability to simplify complex topics, Stephen has been mentoring engineers beginning their careers in software development for years, and has now expanded that experience onto Udemy, authoring the highest rated React course. He teaches on Udemy to share the knowledge he has gained with other software engineers. Invest in yourself by learning from Stephen's published courses.
402 lessons
Easy to follow lectures and videos covering subject details.
31 hours
This course includes hours of video material. Watch on-demand, anytime, anywhere.
Certificate of Completion
You will earn a Certificate of Completion at the end of this course.
Course curriculum
- How to Get Help01:03
- Course Resources00:38
- Join Our Community!00:07
- Course Organization03:29
- Dart Overview02:43
- The Dartpad Editor02:18
- Our First Program02:32
- Pulling the Pieces Apart02:44
- Functions in Dart03:36
- Introduction to Types08:36
- Why Use Types?05:36
- String Interpolation03:19
- Object Oriented Programming in Dart03:12
- Creating Classes04:33
- Creating Class Instances03:57
- Constructor Functions07:26
- Review on Constructors03:41
- App Overview01:12
- OOP Design Flow03:19
- Adding Fields to Classes05:59
- Associated Methods01:22
- More Initialization with Constructors02:52
- For Loops03:08
- Adding Elements to Lists03:56
- More on Variable Initialization04:46
- Customizing Print Statements03:35
- ToString on Cards04:30
- Shuffling a List06:11
- Annotating Argument Types04:42
- Filtering Lists03:46
- Annotating Argument Types02:39
- Filtering Lists05:49
- Shorthand Function Syntax07:14
- Removing Individual Records02:45
- RemoveCard Implementation06:08
- Named Parameters04:00
- Flutter Setup on MacOS02:01
- SDK Extraction02:02
- Editing the PATH Variable07:46
- XCode License01:24
- Generating Flutter Projects01:20
- Android Setup on MacOS01:57
- Android Dependencies01:17
- Android Project Setup01:13
- More Android Dependencies!01:25
- Android Emulator Creation01:51
- Flutter Startup01:27
- Finished Android Setup00:23
- iOS on Mac Setup01:06
- XCode Setup00:36
- iOS Simulator Startup01:44
- App Startup00:23
- Flutter Install03:39
- More Flutter Installation02:47
- Android Install00:47
- Additional Dependencies01:03
- Generating a Project00:53
- Selecting an Image01:49
- Starting the Emulator03:18
- Finishing Android Setup00:23
- Code Editor Setup00:41
- What's Flutter About, Anyways?05:53
- App Overview02:07
- The Four Step Design Process04:14
- Import Statements04:36
- Creating Widgets04:56
- Displaying Content on Screen02:30
- Showing a Scaffold06:09
- Customizing the App Bar03:57
- Named Parameter Clarification05:02
- Required Parameters03:19
- Child Parameters02:17
- Displaying Icons05:48
- Adding Custom Widgets03:49
- Stateless vs Stateful Widgets04:15
- The Build Method04:00
- Local Import Statements05:34
- Quick Breather and Review03:17
- Refactoring Stateless to Stateful05:41
- More Refactoring to Stateful Widgets08:38
- Generics in Dart06:33
- Why Two Classes?06:24
- Photos API03:06
- Working with JSON05:25
- Casting JSON to Model Instances04:02
- Named Constructors06:36
- Adding an Image Model05:44
- Function References03:41
- The HTTP Package04:08
- Issuing HTTP Requests02:54
- Handling Dart Futures07:50
- Parsing Future Responses into a Model04:17
- Updating the AppState Widget03:41
- Building Lists of Widgets04:57
- Sending Images to the ImageList03:35
- The Final Keyword05:32
- Building Lists with ListView05:55
- Listing URL's01:38
- Text to Images03:56
- Containers for Positioning08:07
- Adding Border Style07:18
- Column Widgets for Layout09:18
- Selective Padding05:05
- App Review04:47
- App Overview05:26
- Boilerplate App Code04:50
- Creating the Login Screen06:32
- More Container Styling04:30
- Labels and Hint Text08:45
- Customizing Keyboard Type03:21
- Handling Password Inputs05:09
- Displaying Buttons with RaisedButton04:11
- Changing Widget Colors01:35
- Layout Control08:05
- Form Validation03:44
- Referencing Widgets with Global Keys04:24
- The Form Widget and FormState05:18
- Creating a Global Key02:09
- Referencing FormState with Global Keys04:30
- Validating via FormState05:55
- Triggering Validation06:37
- Retrieving Form Values06:31
- Final Form Submittal04:02
- Code Reuse with Mixins03:53
- Mixin Validator Implementation05:10
- A Quick Detour01:00
- Streams by Analogy05:59
- Characteristics of Streams04:08
- StreamControllers and Sinks05:18
- Mapping a Stream02:39
- Adding a StreamTransformer04:25
- Implementing the Listener03:27
- Stream Review07:51
- Let's Build a Game05:35
- Why Streams?09:46
- Word Guessing05:32
- Stream's 'Take' and 'Where' Functions06:08
- Validation with Streams05:56
- Email Validation04:19
- Wiring up the Error04:35
- BLOC's vs Stateful Widgets06:42
- The Purpose of Streams with Blocs07:39
- Generating a New Project00:55
- App Boilerplate03:05
- Second Time on LoginScreen03:13
- TextFields with RaisedButtons07:48
- How to Use TextFields03:17
- BLOC Design for TextFields04:03
- Annotating Stream Types05:01
- Issues with Bloc Access06:26
- Shortcut Access with Getters08:40
- Public vs Private Fields07:32
- Improving the BLOC Api04:07
- Validation Transformers06:52
- A Technicality Around Mixins04:25
- Cleaning Up Controllers03:18
- Bloc Application06:49
- The StreamBuilder Widget11:26
- Streambuilder for Password Fields04:18
- Scoped Bloc Approach03:08
- Provider Implementation05:37
- The Provider's 'of' Function07:33
- The Provider's Constructor02:16
- The Provider in Action03:19
- Accessing the Bloc05:32
- Breather and Review05:37
- Enabling Form Submission05:16
- Stream Merging Possibilities04:07
- Introducing RxDart04:13
- More on RxDart05:52
- The CombineLatest Function10:06
- CombineLatest in Action06:38
- More on StreamBuilder03:38
- Interpreting Stream Values05:57
- Broadcast Streams04:41
- Disabled by Default03:13
- Replacing Controllers with Subjects08:20
- Review of BLOCs03:23
- App Overview02:52
- Animation Library Classes10:37
- App Boilerplate02:47
- StatefulWidgets for Animations04:19
- Widget Structure02:26
- Displaying a Cat03:44
- The InitState Method03:54
- Declaring the TickerProvider05:45
- Tweens with Curves05:43
- Performance Savings with AnimatedBuilder05:02
- Nature of Animation07:01
- Starting the Animation01:47
- Watching for Taps with GestureDetector04:59
- Reversing Animation States06:34
- Building the Box03:26
- Layouts with the Stack Widget02:43
- Order of Drawing Widgets02:51
- Add Center Widget03:32
- Positioned Widgets11:06
- Expanding Stack Dimensions06:57
- Three Reasons for Strange Layouts07:16
- Positioned Constraints03:57
- Negative Offsets03:56
- Stack Clip Settings03:45
- Adjusting Tween Ranges02:18
- Adding Box Flaps03:28
- Rotating Widgets06:13
- Rotation by Radians06:14
- Changing Rotation Point03:37
- A Touch of Positioning05:18
- BoxAnimation Controller06:59
- Adding Animated Builders06:27
- Resetting Animations04:09
- Constraining Animation Range04:20
- Adding the Right Flap03:14
- Negative Rotation Values04:05
- Toggling Animation State02:36
- Animation Wrapup02:49
- App Overview03:08
- Hacker News API08:50
- More API Challenges08:03
- API Performance Strategy08:27
- Creating the ItemModel Class08:38
- A Few More ItemModel Properties05:24
- API Provider Implementation06:45
- Fetching Individual Items08:32
- Testing with Dart04:43
- A Few Imports05:09
- Writing Expectations05:22
- Mocking HTTP Requests05:52
- Returning JSON05:42
- Testing FetchItem05:17
- SQLite DB Provider04:03
- Database Imports04:27
- Async Constructors02:21
- Creating a DB Connection05:09
- Creating Tables with SQLite03:41
- Adding Table Columns04:22
- Issuing Queries07:55
- Multiple Named Constructors04:31
- Massaging DB Return Maps04:30
- Turning Class Instances to Maps08:41
- Implementing the Repository04:05
- More on the Repository07:08
- Type Annotations06:12
- Casting Lists03:31
- More on the Repository02:45
- Abstract Classes07:02
- The Need for Abstract Classes04:27
- Why Abstract Classes?07:34
- More on Abstract Classes07:02
- Repository Interface Design07:16
- Defining the Source05:52
- Cache Definitions02:08
- Lists of Sources and Caches03:30
- Ultimate Reusability04:05
- Quick Gotcha02:18
- Another Quick Gotcha!01:07
- FetchTopIds Implementation02:28
- App Setup02:45
- A Touch of Boilerplate02:45
- Data Fetching Concerns10:12
- Solution Outline03:21
- FutureBuilder in Action12:04
- The Stories Provider06:02
- Bloc Design06:49
- Exposing Bloc Getters03:32
- Wiring up the Stories Provider03:19
- Bloc Testing07:51
- Type Annotations Solve Problems03:22
- Circular Progress Indicator03:20
- Item Fetching Architecture07:01
- Giant Gotcha with StreamBuilder08:33
- Giant Gotcha Solution07:16
- Implementing ScanStreamTransformer05:38
- Finishing the ScanStreamTransformer02:27
- Adding the Items Controller03:49
- A Gotcha Around Streams? Impossible!03:28
- Single Transformer Application03:46
- The ListView Tile04:07
- StreamBuilder Setup03:27
- Wrapping Up the FutureBuilder03:56
- Double Gotcha!03:56
- Stream Subscriptions10:01
- Stream Subscription Fix01:13
- Additional Streams02:37
- A Laborious Refactor08:42
- Result of Refactor02:28
- Quick Debug Session03:57
- Resolving Database Conflicts09:00
- Building Story Tiles05:18
- Comments Icon04:43
- Applying Dividers with Height05:36
- Loading Container Stand-in03:23
- Building the Loading Container04:20
- Showing the Loading Container02:55
- Long-Lived Cache Values02:35
- Swipe to Refresh Indicator02:54
- Implementing a Refresh Widget04:33
- Clearing Database Tables07:51
- Communicating a Future to onRefresh08:22
- Navigation in Flutter04:05
- Map Based Routing05:56
- OnGenerateRoute-Based Navigation03:39
- OnGenerateRoute Implementation06:34
- Navigating in Style!10:05
- A PageRoute for NewsDetail07:25
- A Scaffold in NewsDetail03:41
- Parsing Route Settings04:42
- The Comments Bloc Provider06:04
- Comments Bloc Design05:11
- More on Comments Bloc07:35
- Recursive Data Fetching12:46
- Quick Fix00:17
- Connecting the Comments Provider03:42
- Testing Recursive Fetching03:22
- Consuming the Item Map05:15
- Displaying the Story Title05:48
- Text Styling06:14
- Container Alignment05:31
- Building the Comments List07:29
- More Logic Extraction04:38
- The Comment Widget05:01
- Comment's FutureBuilder03:21
- Showing Individual COmments06:34
- Recursive Rendering05:50
- Styling the Comment List04:26
- Defaulting Null Values03:37
- Handling Deleted Comments02:56
- Nested Comments03:26
- ListTile's ContentPadding Property05:24
- Replacing Placeholder Characters05:14
- Loading Containers for Comments02:56
- App Wrapup06:10
- Last Fix!01:41
- Dart Local Installation02:38
- Dart Install on Mac03:23
- Editor Setup for Dart03:43
- App Overview02:38
- Folder and File Structure06:43
- The PubSpec File03:08
- Running Dart Files03:58
- Program Design Methodology08:15
- Class Creation02:38
- Terminal Design03:15
- Terminal Implementation02:14
- Stdout and Stdin05:17
- Import Statements06:24
- Stdout Instance04:35
- More on Import Statements09:54
- Testing the Import Class03:22
- Checking Operating System03:51
- Clearing Windows Terminal02:23
- Clearing Other Terminals01:07
- Testing ClearScreen01:22
- Collecting Input Over Stdin07:11
- Option Class FIelds07:07
- Adding Dynamic Fields02:14
- Printing Individual Options06:58
- Testing Option Printing04:36
- List Shortcomings04:35
- Maps in Dart11:35
- Refactor to Maps03:43
- The Prompter Class04:00
- Testing the Prompter03:54
- Extracting the Terminal04:29
- Var vs Final for Variables07:01
- Final's Affect on Values06:01
- Const's Dual Nature06:22
- Const's Behavior by Type12:02
- Marking Terminal as Const02:12
- Private Variables07:22
- Finishing Prompter05:35
- Error Handling03:25
- Asking Binary Questions04:04
- Testing Binary Inputs04:20
- Code Similarities04:33
- Refactor for Code Reuse05:00
- More on Private05:15
- Central Lib File02:44
- A Single Export Point03:09
- A Relevant Example File03:16
- Outstanding Project Config02:53
- Uploading the Prompter Lib05:40
- App Overview02:51
- Project Setup04:05
- Importing Library Code05:37
- Forcibly Exiting a Program04:09
- Prompting for File Type03:27
- Implementation Flow04:13
- Working with the Current Directory05:07
- Filtering Non-Files07:13
- Filtering Non-Images03:29
- Building Options from Images06:03
- Testing Image Selection02:29
- Converting Images06:06
- The ConvertImage Function03:03
- Reading File Contents03:40
- Encoding to JPG or PNG03:39
- Writing Files to the Hard Drive05:33
- Returning the Image Name01:42
- Testing Image Conversion02:37
- Opening the Image03:23
- Bonus!00:29
Online Courses
Learning Flutter doesn't have to be hard. Here is our curated list of recommended online courses that will guide you step-by-step in the learning process.
Learn moreBooks
Are you an avid book reader? Do you prefer paperback, or maybe Kindle version? Take a look at our curated list of Flutter related books and take your
YouTube videos
The number of high-quality and free Flutter video tutorials is growing fast. Check this curated list of recommended videos - there is no excuse to stop learning.
Learn more