On this page23 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. Column — Top to Bottom
- 2. Row — Left to Right
- 3. Main Axis and Cross Axis
- 4. crossAxisAlignment
- 5. Gaps: spacing and SizedBox
- 6. mainAxisSize
- 7. Expanded — Take the Rest
- 8. flex — Share the Space
- 9. Spacer
- 10. The Overflow Error
- 11. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 004 — Row & Column
| Category | 2 — Layout Widgets |
| Lecture | 004 of 009 |
| Estimated video length | 20 min |
| Target | Flutter 3.44 · Dart 3.12 |
| Level | Beginner |
Until now every screen held one widget, and we hid multi-line text behind
\n.RowandColumntake a whole list of children and lay them out side by side or top to bottom — the way almost every real screen is built.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every screenshot and error message in this lecture is real. Each app was run on Flutter 3.44, and each error was produced by the code shown.
Prerequisites
Students should already understand, from Lectures 001–003:
- screens built from
Scaffold,AppBarand aStatelessWidget Padding,SizedBox,Alignand the "constraints go down, sizes go up" ruleContainer,BoxDecorationandTextStyle- Dart
Lists from the Dart course:[a, b, c]
Connection With Previous Lectures
In Lecture 003 Zayan's bank card showed his name and balance with a single Text and \n. That
trick breaks down fast: the two lines cannot have different styles, and we could never put an
avatar next to the name. A screen is really a stack of rows — a header, a line of details, a
total — and each row is a line of pieces. We need widgets that hold many children.
Learning Objectives
By the end of this lecture you will be able to:
- Lay out children vertically with
Columnand horizontally withRow - Explain the main axis and the cross axis of each
- Position children with
mainAxisAlignmentandcrossAxisAlignment - Add gaps with
spacingorSizedBox, and shrink aColumnwithmainAxisSize - Share space with
Expanded,flexandSpacer - Recognize the overflow stripes and fix them
- Nest
Rows insideColumns to build real layouts
1. Column — Top to Bottom
Column takes a children list and places them one below the other:
body: const Column(children: [Text('Ali'), Text('Sara'), Text('Zayan')]),
children is an ordinary Dart List<Widget> — square brackets, commas between items, and a
trailing comma at the end.
Analogy — a
Columnis a stack of books on a shelf, top to bottom; aRowis the same books standing side by side. The shelf decides where the books go; each book only decides its own size.
Notice the names are centered under each other but sit at the left of the screen. A Column
is only as wide as its widest child — "Zayan" — and centers the others inside that width.
2. Row — Left to Right
Row works the same way, horizontally:
body: Row(
children: [
Container(
width: 80,
height: 80,
color: Colors.red.shade200,
alignment: Alignment.center,
child: const Text('A'),
),
Container(
width: 80,
height: 80,
color: Colors.green.shade200,
alignment: Alignment.center,
child: const Text('B'),
),
Container(
width: 80,
height: 80,
color: Colors.blue.shade200,
alignment: Alignment.center,
child: const Text('C'),
),
],
),
3. Main Axis and Cross Axis
Every Row and Column has two directions:
| Main axis (the direction children follow) | Cross axis (the other direction) | |
|---|---|---|
Column | vertical ↓ | horizontal → |
Row | horizontal → | vertical ↓ |
mainAxisAlignment decides where children go along the main axis:
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 80,
height: 80,
color: Colors.red.shade200,
alignment: Alignment.center,
child: const Text('A'),
),
Container(
width: 80,
height: 80,
color: Colors.green.shade200,
alignment: Alignment.center,
child: const Text('B'),
),
Container(
width: 80,
height: 80,
color: Colors.blue.shade200,
alignment: Alignment.center,
child: const Text('C'),
),
],
),
There are six options. Here they are all at once, each on a grey Row:

start,center,end— push the group to one end or the middle.spaceBetween— first and last touch the edges; the free space goes between.spaceAround— every child gets equal space on both sides (so the outer gaps are half size).spaceEvenly— every gap, including the outer ones, is equal.
4. crossAxisAlignment
crossAxisAlignment places children across the main axis. In this Row the boxes have
different heights:
body: Container(
height: 160,
color: Colors.grey.shade200,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 80,
height: 40,
color: Colors.red.shade200,
alignment: Alignment.center,
child: const Text('A'),
),
Container(
width: 80,
height: 80,
color: Colors.green.shade200,
alignment: Alignment.center,
child: const Text('B'),
),
Container(
width: 80,
height: 120,
color: Colors.blue.shade200,
alignment: Alignment.center,
child: const Text('C'),
),
],
),
),
start lines them up at the top; center (the default) through their middles; end along the
bottom. The fourth option, stretch, makes every child as big as the cross axis allows:
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(height: 48, color: Colors.indigo.shade100),
const SizedBox(height: 12),
Container(height: 48, color: Colors.indigo.shade200),
const SizedBox(height: 12),
Container(height: 48, color: Colors.indigo.shade300),
],
),
),
None of these Containers has a width — stretch gave them the full width.
5. Gaps: spacing and SizedBox
Row and Column have a spacing parameter that puts the same gap between every pair of
children:
body: Padding(
padding: const EdgeInsets.all(16),
child: Row(
spacing: 16,
children: [
Container(
width: 80,
height: 80,
color: Colors.red.shade200,
alignment: Alignment.center,
child: const Text('A'),
),
Container(
width: 80,
height: 80,
color: Colors.green.shade200,
alignment: Alignment.center,
child: const Text('B'),
),
Container(
width: 80,
height: 80,
color: Colors.blue.shade200,
alignment: Alignment.center,
child: const Text('C'),
),
],
),
),
When gaps should differ, put a SizedBox(height: …) (in a Column) or SizedBox(width: …)
(in a Row) between the children, as in the stretch example above.
6. mainAxisSize
By default a Column is as tall as it is allowed to be — that is how MainAxisAlignment.end
could push children to the bottom. MainAxisSize.min makes it only as tall as its children:
body: Center(
child: Container(
padding: const EdgeInsets.all(16),
color: Colors.amber.shade100,
child: const Column(
mainAxisSize: MainAxisSize.min,
children: [Text('Only as tall'), Text('as its children')],
),
),
),
Without mainAxisSize: MainAxisSize.min, the amber Container would stretch from the top of the
body to the bottom.
7. Expanded — Take the Rest
Expanded makes a child fill the space left over after the other children are laid out:
body: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(width: 80, height: 80, color: Colors.red.shade200),
Expanded(
child: Container(height: 80, color: Colors.green.shade200),
),
Container(width: 80, height: 80, color: Colors.blue.shade200),
],
),
),
The green Container has no width — Expanded gives it everything the two fixed boxes did not
use. That is how a screen adapts to every phone width.
8. flex — Share the Space
When several children are Expanded, they share the leftover space. flex sets each one's
share:
body: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
height: 80,
color: Colors.red.shade200,
alignment: Alignment.center,
child: const Text('flex: 2'),
),
),
Expanded(
child: Container(
height: 80,
color: Colors.blue.shade200,
alignment: Alignment.center,
child: const Text('flex: 1'),
),
),
],
),
),
The space is split into 2 + 1 = 3 parts; the red box gets 2 of them. flex defaults to 1, so
three plain Expanded children get equal thirds.
9. Spacer
Spacer() is an empty Expanded — it pushes its neighbors apart:
body: const Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
Text('Total'),
Spacer(),
Text('Rs. 750', style: TextStyle(fontWeight: FontWeight.bold)),
],
),
),
10. The Overflow Error
What if the children need more space than the Row has?
body: Row(
children: [
Container(width: 60, height: 60, color: Colors.orange),
const Text(
'Sara ordered three notebooks, two pens and a very large geometry box',
),
],
),
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞══════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 154 pixels on the right.A Row gives every non-Expanded child as much width as it asks for, and a long Text asks for
its full one-line width. The yellow and black stripes mark the edge that overflowed (they only
appear in debug builds — in a release build the text is simply cut off).
The fix: wrap the Text in Expanded. Now it receives only the leftover width and wraps onto
more lines:
body: Row(
children: [
Container(width: 60, height: 60, color: Colors.orange),
const SizedBox(width: 12),
const Expanded(
child: Text(
'Sara ordered three notebooks, two pens and a very large geometry box',
),
),
],
),
11. A Real-World Example
Ali's result card: a Column of Rows inside a decorated Container. It uses an avatar circle,
Expanded, spaceBetween, stretch, spacing and MainAxisSize.min.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.blue),
home: const ResultScreen(),
);
}
}
class ResultScreen extends StatelessWidget {
const ResultScreen({super.key});
@override
Widget build(BuildContext context) {
String name = 'Ali';
int math = 80;
int science = 75;
int english = 85;
int total = math + science + english;
return Scaffold(
appBar: AppBar(title: const Text('Result')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 10,
offset: Offset(0, 4),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
spacing: 12,
children: [
Row(
children: [
Container(
width: 48,
height: 48,
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: Text(
name[0],
style: const TextStyle(color: Colors.white, fontSize: 22),
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
name,
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
const Text('Grade A', style: TextStyle(color: Colors.green)),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const Text('Math'), Text('$math')],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const Text('Science'), Text('$science')],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const Text('English'), Text('$english')],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Total',
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
'$total / 300',
style: const TextStyle(fontWeight: FontWeight.bold),
),
],
),
],
),
),
),
);
}
}
name[0] is the first character of the string, from the Dart course — 'A'. Each subject line
is a Row with spaceBetween, so the label sits left and the number right. stretch makes
every Row full width; without it the rows would shrink to their content and spaceBetween
would have no space to spread.
Code Examples
Example 1 — A Centered Title Block
mainAxisAlignment: MainAxisAlignment.center centers vertically; the surrounding Center
centers horizontally.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Example 1')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome', style: TextStyle(fontSize: 32)),
SizedBox(height: 8),
Text('to the Essential Widgets course'),
],
),
),
);
}
}
Example 2 — Bottom-Right Staircase
A Column is only as wide as its widest child, so crossAxisAlignment.end alone would line the
bars up inside a 240-pixel column at the left. SizedBox(width: double.infinity) makes the
column full width first. double.infinity means "as big as allowed".
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Example 2')),
body: SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(width: 120, height: 40, color: Colors.teal.shade100),
Container(width: 180, height: 40, color: Colors.teal.shade200),
Container(width: 240, height: 40, color: Colors.teal.shade300),
],
),
),
);
}
}
Example 3 — Three Equal Columns
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Example 3')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Row(
spacing: 8,
children: [
Expanded(child: Container(height: 60, color: Colors.red.shade200)),
Expanded(
child: Container(height: 60, color: Colors.green.shade200),
),
Expanded(child: Container(height: 60, color: Colors.blue.shade200)),
],
),
),
);
}
}
Example 4 — Shopping Cart Lines
Expanded on the item name pushes the quantities and prices into a neat right-hand column.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.green),
home: const CartScreen(),
);
}
}
class CartScreen extends StatelessWidget {
const CartScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Cart')),
body: const Padding(
padding: EdgeInsets.all(16),
child: Column(
spacing: 12,
children: [
Row(
children: [
Expanded(child: Text('Notebook')),
Text('3 × 120'),
SizedBox(width: 16),
Text('Rs. 360'),
],
),
Row(
children: [
Expanded(child: Text('Pen')),
Text('5 × 30'),
SizedBox(width: 16),
Text('Rs. 150'),
],
),
Row(
children: [
Expanded(
child: Text(
'Total',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Text('Rs. 510', style: TextStyle(fontWeight: FontWeight.bold)),
],
),
],
),
),
);
}
}
Example 5 — Bank Overview
A full-width balance card above a Row of two equal Expanded boxes.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const BankScreen(),
);
}
}
class BankScreen extends StatelessWidget {
const BankScreen({super.key});
@override
Widget build(BuildContext context) {
int income = 40000;
int expense = 15000;
return Scaffold(
appBar: AppBar(title: const Text('Bank')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
spacing: 16,
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Balance',
style: TextStyle(color: Colors.white70),
),
Text(
'Rs. ${income - expense}',
style: const TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
],
),
),
Row(
spacing: 16,
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(16),
color: Colors.green.shade100,
child: Text('Income\nRs. $income'),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(16),
color: Colors.red.shade100,
child: Text('Expense\nRs. $expense'),
),
),
],
),
],
),
),
);
}
}
Example 6 — Header, Content, Footer
Expanded works vertically too: the middle part fills the space between a fixed header and
footer.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Example 6')),
body: Column(
children: [
Container(height: 120, color: Colors.purple.shade200),
Expanded(child: Container(color: Colors.purple.shade50)),
Container(height: 60, color: Colors.purple.shade300),
],
),
);
}
}
Common Beginner Mistakes
1. child instead of children
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Column(child: Text('Ali')),
),
),
);
}error • The named parameter 'child' isn't defined. Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'child' • lib/main.dart:7:22 • undefined_named_parameterRow and Column take children: [ ... ], even for a single child.
2. Forgetting the list brackets
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Column(children: Text('Ali'), Text('Sara')),
),
),
);
}error • A value of type 'Text' can't be assigned to a parameter of type 'List<Widget>' in a const constructor. Try using a subtype, or removing the keyword 'const' • lib/main.dart:7:22 • const_constructor_param_type_mismatch
error • The argument type 'Text' can't be assigned to the parameter type 'List<Widget>'. • lib/main.dart:7:32 • argument_type_not_assignable
error • Too many positional arguments: 0 expected, but 1 found. Try removing the extra positional arguments, or specifying the name for named arguments • lib/main.dart:7:45 • extra_positional_arguments_could_be_namedchildren needs a list: children: [Text('Ali'), Text('Sara')].
3. A long Text in a Row
The overflow stripes from section 10. Wrap the text in Expanded.
4. Expanded outside a Row or Column
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Oops')),
body: Center(
child: Expanded(child: Container(color: Colors.red)),
),
);
}
}
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞════════════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData
of type FlexParentData to a RenderObject, which has been set up
to accept ParentData of incompatible type BoxParentData.
Usually, this means that the Expanded widget has the wrong
ancestor RenderObjectWidget. Typically, Expanded widgets are
placed directly inside Flex widgets.
The offending Expanded is currently placed inside a CenterExpanded, Flexible and Spacer only work as direct children of a Row, Column (or
Flex). Here it happens to draw, but Flutter reports the mistake every time the screen is built.
Remove the Expanded, or put it inside a Row/Column.
Best Practices
- Use
spacingfor even gaps, and aSizedBoxonly where a gap must be different. - Wrap any
Textthat might be long — names, titles, messages — inExpandedwhen it sits in aRow. - Prefer
Expandedandflexover fixed widths, so layouts work on every screen size. - When a
RoworColumndoes not stretch the way you expect, color it (aContainerwith acolor) to see how big it really is. - Break deep nesting into smaller pieces as soon as it gets hard to read — in Lecture 009 we will turn repeated rows into their own widget classes.
Mini Challenge
Build a weather screen for Lahore:
Lahorein 24-pixel text, and below it30°Cin 64-pixel bold text, both centered- a 24-pixel gap
- a row of three equal light-blue boxes (
Colors.lightBlue.shade100) with 8-pixel gaps, showingMon 30°,Tue 32°andWed 29°on two lines each
Try it yourself before opening the solution.
Show solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.lightBlue),
home: const WeatherScreen(),
);
}
}
class WeatherScreen extends StatelessWidget {
const WeatherScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Weather')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
const Text('Lahore', style: TextStyle(fontSize: 24)),
const Text(
'30°C',
style: TextStyle(fontSize: 64, fontWeight: FontWeight.bold),
),
const SizedBox(height: 24),
Row(
spacing: 8,
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(12),
color: Colors.lightBlue.shade100,
child: const Column(children: [Text('Mon'), Text('30°')]),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(12),
color: Colors.lightBlue.shade100,
child: const Column(children: [Text('Tue'), Text('32°')]),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(12),
color: Colors.lightBlue.shade100,
child: const Column(children: [Text('Wed'), Text('29°')]),
),
),
],
),
],
),
),
);
}
}
How it works
- The outer
Columncenters its children horizontally by default. - The
Rowusesspacing: 8, and each day isExpanded, so the three boxes are equal. - Each box holds a small
Columnwith the day and the temperature.
Practice Questions
Beginner
- Show
Ali,SaraandZayanin aColumnin the exact center of the screen. - Show red, green and blue 60 × 60 squares in a
Row, with the first and last touching the 16-pixel padding. - Show a bold 24-pixel title
Flutter Essentialswith the lineLecture 004 — Row & Columnunder it, both left-aligned.
Application
- Make an orange box take two thirds of the width and a purple box one third, both 100 tall.
- Use
Spacerto showTotalat the left andRs. 750at the right. - In a rounded light-orange card, show
Karachiat the left and a bold34°Cat the right, both 20 pixels. - Show
Icons.infofollowed by this text without an overflow: "Zayan, your monthly statement is ready. Open the app to see every deposit and withdrawal."
Challenge
- Store Sara's marks (
math = 90,science = 85). Show her name in bold 28-pixel text, one full-width row per subject (label left, mark right), and a light-blue total row showing175 / 200, calculated in the string.
Practice Answers
Question 1 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 1')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [Text('Ali'), Text('Sara'), Text('Zayan')],
),
),
);
}
}
Question 2 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 2')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(width: 60, height: 60, color: Colors.red),
Container(width: 60, height: 60, color: Colors.green),
Container(width: 60, height: 60, color: Colors.blue),
],
),
),
);
}
}
Question 3 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 3')),
body: const Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Flutter Essentials',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Text('Lecture 004 — Row & Column'),
],
),
),
);
}
}
Question 4 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 4')),
body: Row(
children: [
Expanded(
flex: 2,
child: Container(height: 100, color: Colors.orange),
),
Expanded(child: Container(height: 100, color: Colors.purple)),
],
),
);
}
}
Question 5 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 5')),
body: const Padding(
padding: EdgeInsets.all(16),
child: Row(children: [Text('Total'), Spacer(), Text('Rs. 750')]),
),
);
}
}
Question 6 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 6')),
body: Container(
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.orange.shade50,
borderRadius: BorderRadius.circular(12),
),
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Karachi', style: TextStyle(fontSize: 20)),
Text(
'34°C',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
],
),
),
);
}
}
Question 7 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Question 7')),
body: const Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
Icon(Icons.info),
SizedBox(width: 8),
Expanded(
child: Text(
'Zayan, your monthly statement is ready. Open the app to see every deposit and withdrawal.',
),
),
],
),
),
);
}
}
Question 8 — Solution
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.blue),
home: const ReportScreen(),
);
}
}
class ReportScreen extends StatelessWidget {
const ReportScreen({super.key});
@override
Widget build(BuildContext context) {
String name = 'Sara';
int math = 90;
int science = 85;
return Scaffold(
appBar: AppBar(title: const Text('Report')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
spacing: 8,
children: [
Text(
name,
style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const Text('Math'), Text('$math')],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const Text('Science'), Text('$science')],
),
Container(
padding: const EdgeInsets.all(12),
color: Colors.blue.shade50,
child: Row(
children: [
const Text('Total'),
const Spacer(),
Text(
'${math + science} / 200',
style: const TextStyle(fontWeight: FontWeight.bold),
),
],
),
),
],
),
),
);
}
}
Quick Revision
- What is the main axis of a
Column? - Which parameter of a
Rowputs space between children:mainAxisAlignmentorcrossAxisAlignment? - What is the difference between
spaceAroundandspaceEvenly? - What does
CrossAxisAlignment.stretchdo in aColumn? - What does
MainAxisSize.minchange? - How much space does an
Expandedchild get? - Two children have
flex: 3andflex: 1. What share does each get? - What causes the yellow and black stripes, and what is the usual fix?
Key Takeaways
Columnlays children top to bottom;Rowleft to right. Both takechildren: [ ... ].- The main axis follows the children; the cross axis goes across.
mainAxisAlignmentspreads children along the main axis;crossAxisAlignmentlines them up across it.spacingadds even gaps;MainAxisSize.minshrinks the widget to its children.Expandedfills leftover space,flexshares it,Spaceris emptyExpandedspace.- Overflow stripes mean the children need more room than they have — usually fixed with
Expanded.
What's Next?
Lecture 005 — Stack & Positioned. Row and Column place widgets next to each other. Next
we place them on top of each other — a badge on a corner, text over a banner, a button floating
over a card — with Stack and Positioned.