Same Dart you know. New superpower — pixels on a screen. Today: your first real UI.
Press J to jump. Arrow keys to navigate.
7 days of variables, functions, classes, async. That's the language. Now we add the toolkit.
int, String, bool, List, Map
Define once, call anywhere
Blueprints for objects
Wait for slow stuff
Many values over time
Code from pub.dev
Dart runs the logic. Flutter draws the screen.
The language
The UI toolkit
Real pixels
Text? Widget. Button? Widget. Padding? Widget. Even the screen itself? Widget. They nest inside each other like LEGO.
If you wonder "is this a widget?" — yes.
One command. Done. Flutter writes ~30 files for you.
Scaffold the project
Move into the folder
Boot on your phone
Don't panic. You'll mostly live in lib/.
Like every Dart program, Flutter starts at main(). Inside, one magic line: runApp(...).
runApp takes one widget and paints it on the whole screen. That widget is your app.
The wrapper that gives your app its look. Pick one based on the platform you want to feel native on.
Google's design
Apple's design
Most Flutter apps use this. Bold colors, raised buttons, hamburger menus. Looks at home on Android.
Colors, fonts, spacing — one place
Screen-to-screen navigation
AppBar, Scaffold, Drawer, FAB
When in doubt, start with MaterialApp. You can always switch later.
Soft corners, gentle blur, sliding screens. Feels native on iPhone. Optional — only use if your app is iOS-first.
Looks & behaves like iPhone apps
Native iOS gestures built-in
CupertinoButton, CupertinoNavigationBar...
โ Cross-platform app
โ Android-first
โ You're new to Flutter
โ You want one look everywhere
โ iOS-only release
โ App must feel iPhone-native
โ You're cloning an iOS app
โ Apple Store is the priority
90% of beginners go with MaterialApp. We will too.
A parent widget holds children. Children hold their own children. Goes deep.
Every widget has a build(). Inside, it returns more widgets. That's how the tree grows.
Think of build() as: "draw me. given the current context, here's what I look like."
Every widget gets a context. It's a handle that says "here's your spot in the tree." Use it to find parents, themes, screen size.
Where in tree
Get colors, fonts
Screen size
Don't memorize. You'll just keep typing context and Flutter figures it out.
Simple version. Skip the engine internals.
Dart + widgets
Flutter builds tree
Engine draws
You see pixels
Display-only widgets. They show, they don't react.
Words on screen
Built-in symbols
Photos & assets
Boxes that wrap other widgets to give them size, color, or breathing room.
Color, size, border, padding
Empty space, fixed size
Push child inward
Three flavors. Pick by how loud you want them to be.
Bold, raised, primary action
Subtle, secondary
Icon-only tap target
90% of layouts are these two. Row = side by side. Column = top to bottom.
When you want one widget on top of another. Like a badge on an avatar, or text over an image.
Children render in order. First one at the back. Last one on top. Use Positioned to pin them to corners.
Inside Row or Column, wrap a child in Expanded to fill remaining space.
mainAxisAlignment = along the row/column. crossAxisAlignment = the other way.
Make your own widget by extending StatelessWidget and giving it a build(). That's it.
Stateless = once built, it never changes. Perfect for static UI — logos, headers, fixed text.
Add a constructor parameter. Now the same widget can show different text.
Build tiny widgets. Combine them into bigger ones. That's the whole game.
Avatar
NameBlock
FollowBtn
UserCard
3 small widgets = 1 reusable card. Now drop UserCard anywhere in your app.
Two kinds of widgets. The difference: can it change after it's drawn?
A photograph. Once taken, frozen.
A video. It plays, changes, updates.
Stateful widgets come in two parts. The widget itself + a State class that holds the changing data.
When data changes, call setState. Flutter redraws the widget with new values.
User clicks button
You change the data
build() runs again
Screen updates
Click the button. Watch the number change. That's setState in action.
In real Flutter: same thing, but inside setState(() { count++; }).
Same idea. Different boolean. UI swaps based on state.
You change the data. UI doesn't update. You wonder why.
No setState — no rebuild — no UI change. Always wrap state changes in it.
A designer hands you this sketch. Your job: turn it into Flutter widgets.
Look at the sketch. Name each piece. That's your widget tree.
Container holds Row. Row holds Avatar + Column + Button. Done.
Same widgets. Real colors. Real text. Real Flutter.
Building things on the web. Flutter + Astro.
๐ You just built UI from a wireframe.
Dart + UI toolkit = Flutter
flutter create, lib/, main.dart
MaterialApp vs CupertinoApp
Widget tree, build, context
Text, Icon, Image, Button
Row, Column, Stack, Expanded
StatelessWidget, params, compose
Stateful, setState, dynamic UI
Sketch → widgets → real UI
Practice beats theory. Open DartPad or your editor and ship.
Day 9: navigation, multiple screens, passing data between pages. See you there.