Flutter Quiz App Learning Guide
Flutter Quiz App Learning Guide
md 2025-11-20
2. Learning Objectives
. Understand the difference between StatelessWidget and StatefulWidget and when to use
each
. Understand setState() and how it triggers UI rebuilds
. Use conditional rendering to switch screens
. Pass callback functions between widgets
. Create custom widgets for reusable UI
. Use Lists and Maps for data
. Use [Link]() and the spread operator (...) to build widget lists
. Structure data with classes and methods
. Use Google Fonts and asset images
. Implement scrolling widgets (SingleChildScrollView)
. Work with Row, Column, Expanded, and SizedBox for layouts
. Use Container with decorations (gradients, borders, colors)
3. Concept Map
. Dart Basics → Classes, Lists, Maps
Appears in: lib/models/quiz_questions.dart, lib/data/[Link],
lib/results_screen.dart
1 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
2 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Why it matters: Flutter uses widgets for everything. Stateless widgets are simple, predictable, and
performant for static UI.
Code from project:
@override
Widget build(context) { // build() method builds the UI
return Center( // Centers its child widget
child: Column( // Arranges children vertically
mainAxisSize: [Link], // Column takes minimum space
needed
children: [ // List of child widgets
[Link]( // Displays image from assets folder
'assets/images/[Link]',
width: 300, // Sets image width
color: const [Link](150, 255, 255, 255), // Tints
image (opacity 150/255)
),
const SizedBox(height: 80), // Adds 80 pixels of vertical space
Text( // Displays text
'Learn Flutter the fun way!',
style: [Link]( // Uses Google Fonts package
color: const [Link](255, 237, 223, 252), // Text
color (ARGB format)
fontSize: 24, // Font size
),
),
const SizedBox(height: 30), // More spacing
[Link]( // Button with icon and label
onPressed: startQuiz, // Calls the callback when pressed
style: [Link](
foregroundColor: [Link], // Text/icon color
),
icon: const Icon(Icons.arrow_right_alt), // Icon widget
label: const Text('Start Quiz'), // Button text
)
],
),
);
}
}
Minimal example:
3 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
const Text('Hello Flutter!'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: const Text('Click Me'),
),
],
),
),
),
);
}
}
Practice exercises:
. Easy: Create a StatelessWidget that displays your name and age.
Expected: Text showing "Name: [Your Name], Age: [Your Age]"
Hint: Use Text widget with string interpolation: 'Name: $name'
. Moderate: Create a StatelessWidget with three buttons in a Column.
Expected: Three buttons stacked vertically
Hint: Each button needs an onPressed callback (can be empty: () {})
. Challenging: Create a reusable Card widget that takes a title and description as parameters.
Expected: A card with title and description that can be reused
Hint: Add final String title; and final String description; to your widget class
Quick quiz:
4 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
@override
State<Quiz> createState() { // Creates the State object
return _QuizState(); // Returns a new State instance
}
}
5 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
@override
Widget build(context) { // Build method runs after setState()
Widget screenWidget = StartScreen(switchScreen); // Default screen
return MaterialApp(
home: Scaffold(
body: Container(
decoration: const BoxDecoration( // Decorates container
gradient: LinearGradient( // Gradient background
colors: [
[Link](255, 78, 13, 151), // Start color
[Link](255, 107, 15, 168), // End color
],
begin: [Link], // Gradient start point
end: [Link], // Gradient end point
),
),
child: screenWidget, // Display the current screen
),
),
);
}
}
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const CounterApp());
}
6 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
@override
State<CounterApp> createState() => _CounterAppState();
}
void incrementCounter() {
setState(() { // Must wrap changes in setState()
counter++; // Increment the counter
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
Text('Counter: $counter'), // Display state
ElevatedButton(
onPressed: incrementCounter, // Call method when pressed
child: const Text('Increment'),
),
],
),
),
),
);
}
}
Practice exercises:
. Easy: Create a StatefulWidget with a counter that goes from 0 to 5.
Expected: Button that increments counter displayed on screen
Hint: Use setState(() { counter++; }) inside button's onPressed
. Moderate: Create a toggle button that switches between "ON" and "OFF".
Expected: Button that toggles between two states
Hint: Use a bool isOn = false; and toggle it with !isOn in setState
. Challenging: Create a list that adds items when a button is pressed.
Expected: List of items that grows when button is clicked
Hint: Use List<String> items = []; and [Link]('Item $i'); in setState
Quick quiz:
7 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
// lib/[Link], line 47
Widget screenWidget = StartScreen(switchScreen); // Pass function
reference
// lib/start_screen.dart, line 37
onPressed: startQuiz, // Call the function when button is pressed
Minimal example:
import 'package:flutter/[Link]';
void main() {
8 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
runApp(const MyApp());
}
@override
State<MyApp> createState() => _MyAppState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
Text(message),
const SizedBox(height: 20),
CustomButton(
onPress: handleButtonPress, // Pass function to child
),
],
),
),
),
);
}
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPress, // Call function when pressed
child: const Text('Press Me'),
);
}
}
9 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Practice exercises:
. Easy: Create a child widget that calls a parent function to update a text message.
Expected: Button in child widget changes text in parent
Hint: Pass void Function(String) and call it with different messages
. Moderate: Create a parent with a counter and a child button that increments it.
Expected: Counter displayed in parent, button in child increments it
Hint: Pass void Function() callback from parent to child
. Challenging: Create a form with multiple input fields that all report back to parent.
Expected: Multiple text fields that update parent's state when changed
Hint: Each field needs its own callback or use a single callback with an identifier
Quick quiz:
Q1: Why use callbacks instead of direct state access?
Q2: What's the type signature for a function that takes an int and returns nothing?
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
11 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView( // Scrollable list
children: [Link]((person) { // Transform each Person to
Widget
return ListTile(
title: Text([Link]),
subtitle: Text('Age: ${[Link]}'),
);
}).toList(), // Convert iterable to List
),
),
);
}
}
Practice exercises:
. Easy: Create a Book class with title and author properties. Create a list of 3 books.
Expected: Class definition and list of Book instances
Hint: Use final String title; and final String author; in class
. Moderate: Create a method on a class that returns a formatted string.
Expected: Method like String getInfo() that returns "Title by Author"
Hint: Use string interpolation: '$title by $author'
. Challenging: Create a list of Maps, each containing person data, then display them in a ListView.
Expected: ListView showing people's names and ages from Maps
Hint: Use [Link]((person) => ListTile(...)).toList()
Quick quiz:
Q1: What's the difference between List and Map?
Q2: What does const mean when declaring a list?
12 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Explanation:
[Link]() returns List<String>
.map((answer) { ... }) transforms each String into an AnswerButton
... (spread) unpacks the list of AnswerButtons into the children list
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
@override
13 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Practice exercises:
. Easy: Display a list of names as Text widgets using .map().
Expected: Column showing each name as separate Text widget
Hint: children: [Link]((name) => Text(name)).toList()
. Moderate: Create a list of numbers and display each as an ElevatedButton.
Expected: Buttons for each number
Hint: Use ...[Link]((num) => ElevatedButton(...))
. Challenging: Create a list of objects and map them to custom widgets with different colors.
Expected: Each object displayed in a colored container
Hint: Use index in map: [Link]().[Link]((entry) { ... [Link]
... })
Quick quiz:
Q1: What does the spread operator (...) do?
Q2: Why do you need .toList() sometimes but not always?
// lib/start_screen.dart, line 13
mainAxisSize: [Link], // Column only takes minimum space needed
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
15 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
body: Center(
child: Column(
mainAxisAlignment: [Link], // Center
vertically
crossAxisAlignment: [Link], // Center
horizontally
children: [
const Text('First Item'),
const SizedBox(height: 20), // Add 20px spacing
Row(
mainAxisAlignment: [Link],
children: [
Container(
width: 50,
height: 50,
color: [Link],
),
const SizedBox(width: 10), // Horizontal spacing
Expanded( // Fills remaining space
child: Container(
height: 50,
color: [Link],
),
),
],
),
const SizedBox(height: 20),
const Text('Last Item'),
],
),
),
),
);
}
}
Practice exercises:
. Easy: Create a Column with three Text widgets and spacing between them.
Expected: Three text items with gaps
Hint: Use SizedBox(height: 10) between items
. Moderate: Create a Row with a small icon, text, and a button that fills remaining space.
Expected: Icon, text, and expanded button in a row
Hint: Use Expanded around the button widget
. Challenging: Create a responsive layout that works in both portrait and landscape.
Expected: Layout adapts to screen orientation
Hint: Use MediaQuery and conditional Row/Column based on orientation
16 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Quick quiz:
Q1: What's the difference between mainAxisAlignment and crossAxisAlignment?
Q2: When should you use Expanded?
Minimal example:
import 'package:flutter/[Link]';
import 'package:google_fonts/google_fonts.dart';
void main() {
runApp(const MyApp());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [[Link], [Link]],
begin: [Link],
end: [Link],
),
),
child: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
Text(
'Styled Text',
style: [Link](
fontSize: 32,
color: [Link],
fontWeight: [Link],
),
),
const SizedBox(height: 20),
Container(
padding: const [Link](20),
decoration: BoxDecoration(
color: [Link],
borderRadius: [Link](10),
boxShadow: [
BoxShadow(
color: [Link](0.2),
blurRadius: 5,
offset: const Offset(0, 3),
),
],
18 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
),
child: const Text('Box with decoration'),
),
],
),
),
),
),
);
}
}
Practice exercises:
. Easy: Create a Container with a custom background color and rounded corners.
Expected: Colored container with rounded corners
Hint: Use BoxDecoration with color and borderRadius
. Moderate: Use Google Fonts to style different Text widgets with different fonts.
Expected: Multiple text widgets with different font families
Hint: Try [Link](), [Link](), etc.
. Challenging: Create a card with gradient background, shadow, and custom border.
Expected: Card with multiple styling properties
Hint: Combine BoxDecoration with gradient, boxShadow, and border
Quick quiz:
Q1: What does ARGB stand for in [Link]()?
Q2: How do you add shadows to a Container?
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
// Load image from assets
[Link](
'assets/images/[Link]', // Make sure this file
exists!
width: 200,
),
const SizedBox(height: 20),
// Image with color tint
[Link](
'assets/images/[Link]',
width: 200,
color: [Link](0.5), // Blue tint at 50%
opacity
),
],
),
),
),
);
}
}
Practice exercises:
. Easy: Add an image to your project and display it.
20 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
21 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView( // Wraps scrollable content
child: Column(
children: [Link](50, (index) { // Generate 50 widgets
return ListTile(
title: Text('Item ${index + 1}'),
leading: const Icon([Link]),
);
}),
),
),
),
);
}
}
Practice exercises:
. Easy: Create a scrollable list of 20 Text widgets.
Expected: Vertical scrollable list
Hint: Wrap Column with SingleChildScrollView
. Moderate: Create a scrollable form with multiple input fields.
Expected: Form that scrolls when keyboard appears
Hint: Wrap your form widget with SingleChildScrollView
. Challenging: Create both horizontal and vertical scrollable sections.
Expected: Content that scrolls in both directions
Hint: Nest SingleChildScrollView widgets or use ListView with scrollDirection
Quick quiz:
Q1: When should you use SingleChildScrollView?
Q2: What's the difference between SingleChildScrollView and ListView?
return MaterialApp(
// ...
child: screenWidget, // Display the widget based on condition
);
Minimal example:
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
@override
State<MyApp> createState() => _MyAppState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
// Conditional rendering with ternary operator
showDetails
? const Text('Details are visible!')
: const Text('Click to show details'),
23 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
Practice exercises:
. Easy: Show different text based on a boolean state.
Expected: Text changes when button is pressed
Hint: Use ternary operator: condition ? widget1 : widget2
. Moderate: Create a login/logout button that shows different UI for each state.
Expected: Different widgets shown based on login status
Hint: Use if statements or ternary operators
. Challenging: Create a multi-step form that shows different steps based on completion state.
Expected: Form that progresses through steps
Hint: Use a step counter and conditionally render different form sections
Quick quiz:
Q1: What's the difference between using if statements and ternary operators for conditional
rendering?
Q2: When should you use conditional rendering?
24 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
AFTER (Improved):
// ...
}
Improvements:
. Line 20: Use explicit String type instead of var
. Better approach: Use an enum for screen states (see suggestion above)
. Lines 49, 55: Multiple if statements could be replaced with if-else or switch
Suggested refactor:
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
25 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
colors: [
[Link](255, 78, 13, 151),
[Link](255, 107, 15, 168),
],
begin: [Link],
end: [Link],
),
),
child: _buildCurrentScreen(), // Cleaner
),
),
);
}
File: lib/questions_screen.dart
Issue: No bounds checking for currentQuestionIndex
Risk: If user somehow skips questions, could cause RangeError
Fix:
@override
Widget build(BuildContext context) {
// Safety check
if (currentQuestionIndex >= [Link]) {
return const Center(child: Text('No more questions'));
}
File: lib/results_screen.dart
Issue: Line 46 - Missing const keyword
// BEFORE:
style: [Link](
color: [Link](255, 230, 200, 253), // Missing 'const'
// AFTER:
style: [Link](
color: const [Link](255, 230, 200, 253), // Add 'const'
26 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
// BEFORE:
icon: Icon([Link]),
// AFTER:
icon: const Icon([Link]),
Performance suggestion: The getSummaryData() method is called on every build. Consider memoizing:
@override
void initState() {
[Link]();
_summaryData = getSummaryData();
}
File: lib/answer_button.dart
Current code is good! This is a well-structured reusable widget.
Optional enhancement: Add disabled state
const AnswerButton({
[Link],
required [Link],
required [Link],
[Link] = true, // Add default parameter
});
// In build:
onPressed: isEnabled ? onTap : null, // Disable button
File: lib/data/[Link]
Good practice: Using const for immutable data.
Enhancement suggestion: Add question IDs for better tracking
class QuizQuestion {
const QuizQuestion([Link], [Link], [Link]); // Add ID
final String id;
27 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
// ...
}
File: test/widget_test.dart
Issue: Test references MyApp which doesn't exist in this project.
Fix:
import 'package:flutter/[Link]';
import 'package:flutter_test/flutter_test.dart';
import 'package:adv_basics/[Link]';
import 'package:adv_basics/[Link]';
void main() {
testWidgets('Quiz app starts with start screen', (WidgetTester tester)
async {
await [Link](const Quiz()); // Use Quiz widget
. Answering Questions:
QuestionsScreen maintains its own currentQuestionIndex
User selects answer → answerQuestion() called
Calls [Link](answer) → bubbles up to parent's chooseAnswer()
Parent's chooseAnswer() adds answer to selectedAnswers list
If all questions answered → setState() changes activeScreen = 'results-screen'
[Link]() increments currentQuestionIndex → shows next
question
. Showing Results:
[Link]() creates ResultsScreen with selectedAnswers list
[Link]() transforms list into list of Maps
Data flows down: Quiz → ResultsScreen → QuestionsSummary → SummaryItem
State Management Pattern Used
Pattern: Lifting State Up (Flutter's basic pattern)
Main state lives in parent (Quiz)
Child widgets receive callbacks to update parent
Child widgets can have their own local state (QuestionsScreen)
No external state management: This project doesn't use Provider, Bloc, Riverpod, etc.
Async Code Analysis
No async code found in this project. All operations are synchronous.
If you add async code in the future:
29 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
30 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
. Hard-coded widths
Location: lib/start_screen.dart line 17
Issue: width: 300 might not work on all screen sizes
Fix:
. Missing SafeArea
Issue: Content might go under notches/status bars
Fix: Wrap main content in SafeArea widget
31 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
return MaterialApp(
home: Scaffold(
body: SafeArea( // Add this
child: Container(
// ... rest of code
),
),
),
);
Accessibility Improvements
. Add semantic labels:
// For buttons
Semantics(
label: 'Start Quiz Button',
child: [Link](...),
)
// For images
Semantics(
label: 'Quiz logo',
child: [Link](...),
)
// In AnswerButton widget
Semantics(
button: true,
label: 'Answer option: $answerText',
child: ElevatedButton(...),
)
Internationalization (i18n)
32 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
// test/models/quiz_questions_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:adv_basics/models/quiz_questions.dart';
void main() {
group('QuizQuestion', () {
test('getShuffledAnswers returns all answers', () {
const question = QuizQuestion('Test?', ['A', 'B', 'C', 'D']);
final shuffled = [Link]();
expect([Link], 4);
expect([Link]('A'), true);
expect([Link]('B'), true);
expect([Link]('C'), true);
expect([Link]('D'), true);
});
// test/widget/quiz_test.dart
import 'package:flutter/[Link]';
33 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
import 'package:flutter_test/flutter_test.dart';
import 'package:adv_basics/[Link]';
import 'package:adv_basics/[Link]';
void main() {
testWidgets('Quiz app shows start screen initially', (tester) async {
await [Link](const Quiz());
// Start quiz
await [Link]([Link]('Start Quiz'));
await [Link]();
// Complete quiz
await [Link]([Link]('Start Quiz'));
await [Link]();
await [Link]([Link](ElevatedButton).first);
await [Link]();
}
// Tap restart
await [Link]([Link]('Restart Quiz!'));
await [Link]();
Debugging Tips
. Flutter DevTools:
Run flutter pub global activate devtools
Use flutter run and open DevTools
Inspect widget tree, check performance, view logs
. Print debugging:
[Link](answer);
// ...
}
. Breakpoints:
Set breakpoints in VS Code/Android Studio
Inspect variables, step through code
Check call stack
. Common issues:
Overflow errors: Wrap in SingleChildScrollView or use Expanded
setState() errors: Make sure setState() is called from State class
Build context errors: Don't use BuildContext after async operations
Null errors: Use null safety (?, !, ??)
@override
void initState() {
[Link]();
summaryData = _getSummaryData();
}
// Current:
SizedBox(height: 30),
// Better:
const SizedBox(height: 30),
36 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
if ([Link]) {
throw ArgumentError('Answer cannot be empty');
}
Platform-Specific Notes
Android: No special configurations needed
iOS: No special configurations needed
Web: Should work out of the box
Desktop: Should work, but test for appropriate sizing
Read Lesson 3
Understand parent-child communication
Complete practice exercises
Build a form where child widgets update parent
Checkpoint: Create a widget tree with 3 levels passing callbacks
Week 2: Advanced Concepts
Day 8-9: Lists, Maps, Classes
Read Lesson 4
Practice with Lists and Maps
Create your own data model class
Complete practice exercises
Checkpoint: Create a data model with methods
Day 10-11: List Operations & Widget Lists
Read Lesson 5
Practice with .map() and spread operator
Build a dynamic list of widgets
Checkpoint: Create a list that generates widgets from data
Day 12-13: Layout & Styling
Read Lessons 6 & 7
Practice with Column, Row, Expanded
Style widgets with colors and fonts
Complete practice exercises
Checkpoint: Create a styled, responsive layout
Day 14: Integration & Polish
Read remaining lessons (8-10)
Review all code improvements
Apply optimizations to the project
Write a simple test
Final Project: Build your own quiz app with different questions
4-Week Comfortable Plan (30-45 min/day)
Week 1:
Days 1-3: Widgets basics
Days 4-5: StatefulWidget basics
Days 6-7: Practice and review
Week 2:
Days 8-10: Callbacks and communication
Days 11-12: Data structures
39 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
// Display
Text('Hello') // Text widget
[Link]('path') // Load image
Icon([Link]) // Icon
// Input
ElevatedButton(onPressed: ...) // Primary button
OutlinedButton(onPressed: ...) // Outlined button
TextButton(onPressed: ...) // Text button
// Scrolling
SingleChildScrollView(...) // Scrollable content
ListView(...) // Scrollable list
40 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
StatefulWidget Pattern
class MyWidget extends StatefulWidget {
const MyWidget({[Link]});
@override
State<MyWidget> createState() => _MyWidgetState();
}
void increment() {
setState(() { // Must wrap in setState()
counter++;
});
}
@override
Widget build(BuildContext context) {
return Text('$counter');
}
}
Common Operations
// Lists
[Link](item) // Add item
[Link] // Get length
[Link]((item) => ...) // Transform
[Link]((item) => ...) // Filter
...list // Spread operator
// Maps
map['key'] // Get value
map['key'] = value // Set value
[Link]('key') // Check if key exists
// Classes
class MyClass {
final String name; // Immutable property
MyClass([Link]); // Constructor
}
Lifecycle Methods
@override
void initState() { // Called once when widget is created
41 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20
[Link]();
}
@override
Widget build(BuildContext context) { // Called to build UI
return ...;
}
@override
void dispose() { // Called when widget is removed
// Cleanup
[Link]();
}
Flutter Commands
flutter run # Run app
flutter pub get # Install dependencies
flutter clean # Clean build files
flutter test # Run tests
flutter analyze # Check for errors
flutter doctor # Check Flutter setup
Quiz Answers
Lesson 1 Answers
45 / 46
COMPLETE_FLUTTER_LEARNING_GUIDE.md 2025-11-20