# Flutter Mobile 101

> Dart, widgets, then MVVM + dependency injection + screen architecture: read and change a real Flutter app running on Android and iOS.

- URL: https://dantech.academy/en/courses/flutter-mobile-101
- Instructor: Dan Tech
- Curriculum: 26 lessons
- Tiếng Việt: https://dantech.academy/courses/flutter-mobile-101.md

Entry course for Flutter beginners: the Dart and widget foundation, then split the app into three MVVM layers, inject dependencies with the provider package, navigate with a screen state machine, and persist data locally. You learn on a complete app repo - clone it, run it, read it, then change the part each module just taught you.

## Prerequisites

- Newbie
- Laptop (macOS to run iOS)
- 1h/Day

## Skills

- Dart essentials
- Flutter widgets & Material 3
- MVVM architecture
- Provider dependency injection
- Local persistence & testing

## Curriculum

For AI agents: every lesson has a Markdown version at its URL plus `.md`. Free lessons return the full text; lessons for enrolled students return their objectives and outline.

### Setup and First Run

a clean toolchain, an app running on a real device with hot reload, and Git checkpoints as a safety net.

- [Cài Flutter SDK và flutter doctor](https://dantech.academy/en/courses/flutter-mobile-101/00-foundations-setup/lesson-01-install-flutter-sdk.md) (free): Cài Flutter SDK bản stable mới nhất từ repo chính thức của Flutter trên macOS, Windows, Linux, tự gõ lệnh hoặc giao cho AI coding agent, rồi đọc từng dòng flutter doctor và xử lý các cảnh báo thường gặp.
- [flutter create, flutter run và hot reload](https://dantech.academy/en/courses/flutter-mobile-101/00-foundations-setup/lesson-02-first-app-hot-reload.md) (free): flutter create, flutter run trên máy thật, cấu trúc thư mục ở mức cần thiết, và vòng lặp hot reload.
- [Git checkpoint, clone app đích và rules file cho AI](https://dantech.academy/en/courses/flutter-mobile-101/00-foundations-setup/lesson-03-git-checkpoints-ai-pair.md) (free): Commit theo checkpoint, nhận lời mời và clone app TicTac (quyền chỉ đọc) chạy trên máy thật, làm việc trên branch cá nhân, cập nhật code khi khóa học đổi, và khai stack của khóa trong rules file cho AI coding tool.

### Just Enough Dart

read null safety, named params, sealed classes, collections and async in AI-generated code.

- [var, final, named parameters và null safety](https://dantech.academy/en/courses/flutter-mobile-101/01-dart-essentials/lesson-01-null-safety-and-functions.md): final và var, named parameters, null safety với ?. và ??, arrow function - đủ Dart để đọc mọi dòng code trong khóa.
- [Class, sealed class và pattern matching](https://dantech.academy/en/courses/flutter-mobile-101/01-dart-essentials/lesson-02-classes-sealed-and-patterns.md): enum có field và method, class bất biến với const constructor, sealed class, switch expression với pattern matching.
- [List, Map, Future và async/await](https://dantech.academy/en/courses/flutter-mobile-101/01-dart-essentials/lesson-03-collections-and-async.md): map, where, take trên List, cache bằng Map, collection-for và spread trong UI, Future với async/await.

### Widget Fundamentals

the widget tree and layout, state and rebuilds, lists and chips, constraints and sizing, Stack overlays, the three trees with const and keys, BuildContext and InheritedWidget, the State lifecycle with animation.

- [Widget tree, Column, Row và Expanded](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-01-widget-tree-and-layout.md): Column, Row, GridView, Expanded, SizedBox, và cách đọc một widget tree lồng nhiều tầng.
- [StatelessWidget, StatefulWidget và setState](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-02-state-and-rebuilds.md): StatelessWidget với StatefulWidget, setState kích hoạt rebuild, và lifting state up khi nhiều widget dùng chung một state.
- [collection-for, ListView.builder và Chip](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-03-lists-and-selection.md): collection-for trong SingleChildScrollView, khi nào phải đổi sang ListView.builder, và nhóm chip chọn sinh từ enum.values.
- [BoxConstraints, Expanded và LayoutBuilder](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-04-constraints-and-sizing.md): constraints go down, sizes go up, parent sets position; tight, loose và unbounded constraints; Expanded, AspectRatio, ConstrainedBox, FittedBox, LayoutBuilder, SafeArea.
- [Stack, Positioned và IgnorePointer](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-05-stack-and-overlays.md): Stack với Positioned, IgnorePointer cho lớp trang trí, ClipRRect cắt góc, RepaintBoundary cô lập vẽ lại.
- [Widget, Element, RenderObject](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-06-three-trees-const-and-keys.md): Ba nhánh của Element.updateChild, Widget.canUpdate, key quyết định State giữ hay mất, const đưa rebuild vào nhánh bỏ qua.
- [BuildContext và InheritedWidget](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-07-buildcontext-and-inherited-widget.md): BuildContext là node trong element tree, .of(context) tra ngược lên cây, InheritedWidget đứng sau Theme, MediaQuery và provider.
- [State lifecycle và AnimationController](https://dantech.academy/en/courses/flutter-mobile-101/02-widget-essentials/lesson-08-state-lifecycle-and-animation.md): initState, didUpdateWidget, dispose, mounted; AnimationController với TickerProvider; implicit animation so với controller tự cầm.

### MVVM

Model, ViewModel and View - a domain layer with no Flutter imports, plus your first test.

- [MVVM: Model, View, ViewModel in Flutter](https://dantech.academy/en/courses/flutter-mobile-101/03-mvvm/lesson-01-why-mvvm-and-three-layers.md): Ba giới hạn của setState khi app vượt một màn hình, trách nhiệm của Model, ViewModel, View, và tầng domain không import Flutter.
- [Immutable model và sealed class](https://dantech.academy/en/courses/flutter-mobile-101/03-mvvm/lesson-02-model-and-ui-state.md): MatchRecord với == viết tay, ScoreBoard và RoundState trả instance mới thay vì sửa tại chỗ, sealed class cho kết quả một ván và cho một lần đọc dữ liệu, và bài test đầu tiên.
- [ChangeNotifier và ListenableBuilder](https://dantech.academy/en/courses/flutter-mobile-101/03-mvvm/lesson-03-viewmodel-with-changenotifier.md): Ba ViewModel từ mỏng tới dày, ListenableBuilder nối View không cần thư viện ngoài, và dispose() đóng cả một lớp bug.

### Provider and Dependency Injection

push the ViewModel down the tree, inject the repository through the constructor, and test against a fake.

- [Provider, MultiProvider và context.watch](https://dantech.academy/en/courses/flutter-mobile-101/04-provider-di/lesson-01-provider-package-basics.md): provider dựng trên InheritedWidget, MultiProvider ở composition root, và bốn cách đọc: watch, read, select, Consumer.
- [Dependency injection và composition root](https://dantech.academy/en/courses/flutter-mobile-101/04-provider-di/lesson-02-injecting-dependencies.md): buildProviders() đọc từng khối, vì sao không ViewModel nào ở app scope, vì sao repo không dùng ChangeNotifierProxyProvider, và hai seam Clock với Random.
- [Provider scope, Fake và fake_async](https://dantech.academy/en/courses/flutter-mobile-101/04-provider-di/lesson-03-scoping-and-testing.md): Scope quyết định vòng đời, ProviderNotFoundException khi nào là tin tốt, Fake viết tay thay mock framework, và test ViewModel có Timer bằng fake_async.

### Screen Architecture

a five-screen state machine instead of a navigator stack, the system back button, and where each piece of state lives.

- [Navigator stack và screen state machine](https://dantech.academy/en/courses/flutter-mobile-101/05-navigation/lesson-01-screen-state-machine.md): Navigator stack làm gì, vì sao app TicTac đổi màn bằng enum năm giá trị thay vì push và pop, và seam ScreenNavigator một method.
- [AppShell, ValueKey và PopScope](https://dantech.academy/en/courses/flutter-mobile-101/05-navigation/lesson-02-appshell-and-transitions.md): MaterialApp dựng trong AppShell, AppViewModel provide ở shell chứ không app-wide, switch exhaustive chọn màn, ValueKey remount, PopScope cho nút back Android.
- [ViewModel scope và shared repository](https://dantech.academy/en/courses/flutter-mobile-101/05-navigation/lesson-03-where-state-lives.md): Hai màn đọc chung repository thay vì gọi nhau, màn chơi tự mở ván khi hiện lên nên điều hướng là đủ, hiệu ứng ăn mừng sống ở shell, và bảng quyết định state nào đặt ở đâu.

### Assemble the Full App

a four-layer storage stack that fails soft, a layer-boundary checklist, theming, debugging and an installable build.

- [SharedPreferencesAsync và repository pattern](https://dantech.academy/en/courses/flutter-mobile-101/06-full-app/lesson-01-local-persistence-repository.md): Seam KeyValueStore, adapter SharedPreferencesAsync, JSON codec có số version, và repository làm nguồn sự thật với bốn nhánh đọc fail-soft.
- [main(), runApp và ráp toàn bộ app](https://dantech.academy/en/courses/flutter-mobile-101/06-full-app/lesson-02-assemble-the-app.md): main() load dữ liệu trước runApp, năm màn nối nhau ra sao, cây thư mục khi mọi thư mục đã có lý do, và checklist ranh giới tầng kiểm được bằng lệnh.
- [ColorScheme, debug và flutter build](https://dantech.academy/en/courses/flutter-mobile-101/06-full-app/lesson-03-theme-debug-and-ship.md): Hai ColorScheme viết tay thay vì sinh từ một màu, motion token tập trung, ba kỹ năng debug, chín thứ trông như bug mà không phải, và lệnh build cho Android lẫn iOS.
