On this page22 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. One Child, Many Children
  5. 2. Padding — Space Around a Child
  6. 3. The Four EdgeInsets
  7. 4. Align — Put the Child Anywhere
  8. 5. Alignment(x, y) — Any Position
  9. 6. SizedBox — An Exact Size
  10. 7. AspectRatio — Keep the Shape
  11. 8. FittedBox — Scale the Child to Fit
  12. 9. How Layout Works: Constraints Go Down, Sizes Go Up
  13. 10. A Real-World Example
  14. Code Examples
  15. Common Beginner Mistakes
  16. Best Practices
  17. Mini Challenge
  18. Practice Questions
  19. Practice Answers
  20. Quick Revision
  21. Key Takeaways
  22. What's Next?

Lecture 002 — Single-Child Layout Widgets

Category2 — Layout Widgets
Lecture002 of 009
Estimated video length14 min
TargetFlutter 3.44 · Dart 3.12
LevelBeginner

In Lecture 001 the only way to place something was Center. Real screens need space around text, things pinned to corners, and boxes of an exact size — single-child layout widgets do exactly that.

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 Lecture 001:

  • main(), runApp() and MaterialApp
  • Scaffold, AppBar and body
  • Text and Center
  • writing a screen as a StatelessWidget with a build() method

Connection With Previous Lectures

Put a long sentence straight into a Scaffold's body:

A sentence starting at the very left edge of the screen
Text with no space around it

The text is glued to the left edge of the screen. It works, but it looks unfinished, and on a phone with rounded corners the first letters can even be cut off. We need ways to say "leave some space", "put this in the corner" and "make this exactly 200 pixels wide".


Learning Objectives

By the end of this lecture you will be able to:

  • Tell single-child widgets (child) from multi-child widgets (children)
  • Add space around a widget with Padding and the different EdgeInsets constructors
  • Place a widget anywhere inside its parent with Align and Alignment
  • Give a widget an exact size, or empty space, with SizedBox
  • Keep a width-to-height shape with AspectRatio
  • Scale content to fit a box with FittedBox
  • Use ColoredBox to see how much space a widget takes
  • Explain the basic rule of Flutter layout: constraints go down, sizes go up

1. One Child, Many Children

Every layout widget falls into one of two groups:

  • Single-child widgets take one widget in a parameter called child. They change how that one child is placed or sized: Center, Padding, Align, SizedBox…
  • Multi-child widgets take a list of widgets in a parameter called children: Row, Column, Stack. We meet them in Lectures 004 and 005.

Analogy — a single-child layout widget is a picture frame. The frame does not change the picture; it decides how much border goes around it and where it hangs on the wall. And you can put a frame inside another frame.

Because each one holds exactly one child, you build layouts by nesting them.


2. Padding — Space Around a Child

Padding adds empty space between its child and the edges of the space it was given:

dart
body: const Padding(
  padding: EdgeInsets.all(24),
  child: Text(
    'This text has 24 pixels of space on every side. Much easier to read.',
  ),
),
The same sentence, now indented 24 pixels from the left and top
Padding with EdgeInsets.all(24)

padding does not take a plain number — it takes an EdgeInsets object that says how much space goes on each side. Numbers in Flutter layouts are logical pixels: a size that looks about the same on every phone, whatever its screen density.


3. The Four EdgeInsets

ConstructorMeaning
EdgeInsets.all(16)16 on all four sides
EdgeInsets.symmetric(horizontal: 24, vertical: 8)24 left and right, 8 top and bottom
EdgeInsets.only(left: 16, top: 40)only the sides you name; the others are 0
EdgeInsets.fromLTRB(8, 24, 48, 4)left, top, right, bottom — in that order

Padding is invisible, so it is hard to check. Wrap it in a ColoredBox — a widget that paints a color behind its child and does nothing else — and you can see it:

dart
body: const ColoredBox(
  color: Colors.amber,
  child: Padding(
    padding: EdgeInsets.symmetric(horizontal: 40, vertical: 12),
    child: Text('symmetric: 40 left/right, 12 top/bottom'),
  ),
),
An amber strip with text, wider on the left and right than on the top and bottom
symmetric padding made visible

We will use ColoredBox all through this lecture as a debugging aid. In Lecture 003 its big brother, Container, will color, size and decorate in one widget.


4. Align — Put the Child Anywhere

Center always places its child in the middle. Align places it wherever its alignment says:

dart
body: const Align(
  alignment: Alignment.bottomRight,
  child: Padding(
    padding: EdgeInsets.all(16),
    child: Text('Bottom right'),
  ),
),
The text Bottom right in the bottom-right corner of the screen
Align with Alignment.bottomRight

Alignment has nine ready-made positions: topLeft, topCenter, topRight, centerLeft, center, centerRight, bottomLeft, bottomCenter and bottomRight. In fact Center is just an Align whose alignment is always Alignment.center.


5. Alignment(x, y) — Any Position

The nine names are shortcuts for numbers. x runs from -1 (left edge) to 1 (right edge); y runs from -1 (top) to 1 (bottom). Alignment(0, 0) is the center.

dart
body: const Align(
  alignment: Alignment(0.5, -0.5),
  child: ColoredBox(
    color: Colors.lightGreen,
    child: Padding(
      padding: EdgeInsets.all(8),
      child: Text('x: 0.5, y: -0.5'),
    ),
  ),
),
A green label placed right of center and above the middle
Alignment(0.5, -0.5)

0.5 is halfway between the center and the right edge; -0.5 is halfway between the center and the top.


6. SizedBox — An Exact Size

SizedBox forces its child to a fixed width and height:

dart
body: const Center(
  child: SizedBox(
    width: 200,
    height: 120,
    child: ColoredBox(
      color: Colors.lightBlue,
      child: Center(child: Text('200 × 120')),
    ),
  ),
),
A blue 200 by 120 rectangle in the center with the text 200 × 120
SizedBox(width: 200, height: 120)

Give only one of the two and the other dimension is left to the child. SizedBox with no child is the standard way to add an empty gap — SizedBox(height: 16) — which becomes very useful once we put several widgets in a Column in Lecture 004.


7. AspectRatio — Keep the Shape

Sometimes the exact size is not known — phones are different widths — but the shape is. A video player is always 16 : 9; a profile photo is 1 : 1. AspectRatio takes all the width it is given and calculates the height from the ratio:

dart
body: const Padding(
  padding: EdgeInsets.all(16),
  child: AspectRatio(
    aspectRatio: 16 / 9,
    child: ColoredBox(
      color: Colors.orange,
      child: Center(child: Text('Always 16 : 9')),
    ),
  ),
),
A wide orange rectangle across the top of the screen with the text Always 16 : 9
AspectRatio(aspectRatio: 16 / 9)

aspectRatio is width ÷ height. 16 / 9 is about 1.78 — wider than tall. 1 is a square. 0.5 is twice as tall as it is wide.


8. FittedBox — Scale the Child to Fit

FittedBox scales its child up or down until it fits the space, keeping its proportions:

dart
body: const Center(
  child: SizedBox(
    width: 300,
    height: 100,
    child: FittedBox(child: Text('Rs. 25,000')),
  ),
),
Rs. 25,000 drawn very large across the middle of the screen
FittedBox inside a 300 × 100 SizedBox

Normal text is 14 pixels tall. Inside the 300 × 100 box, FittedBox scaled it up until the text filled the width. If the text were wider than the box, FittedBox would shrink it instead — handy for long amounts that must stay on one line.


9. How Layout Works: Constraints Go Down, Sizes Go Up

What happens if a child asks for more space than its parent has?

dart
body: const ColoredBox(
  color: Colors.pink,
  child: SizedBox(width: 1000, height: 100),
),
A pink strip exactly as wide as the screen and 100 pixels tall
A 1000-pixel-wide SizedBox on a 360-pixel screen

The strip is only as wide as the screen. That is Flutter's layout rule:

  1. Constraints go down. Each parent tells its child the smallest and largest size it may be. The screen told the body "at most 360 wide".
  2. Sizes go up. The child picks a size inside those limits and reports it back. The SizedBox wanted 1000, but the most it was allowed was 360 — so it is 360.
  3. The parent positions the child. That is what Center, Align and Padding decide.

Every layout widget in this course is just a different answer to steps 1 and 3.


10. A Real-World Example

Sara's learning app greets her on its home screen. A banner with a 2 : 1 shape sits at the top, 16 pixels from the edges, with the message in its bottom-left corner.

dart
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.teal),
      home: const WelcomeScreen(),
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  const WelcomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    String name = 'Sara';
    int lessonsDone = 3;

    return Scaffold(
      appBar: AppBar(title: const Text('Welcome')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Align(
          alignment: Alignment.topCenter,
          child: AspectRatio(
            aspectRatio: 2,
            child: ColoredBox(
              color: Colors.teal.shade100,
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Align(
                  alignment: Alignment.bottomLeft,
                  child: Text(
                    'Welcome back, $name! Lessons done: $lessonsDone',
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
A light teal 2-to-1 banner at the top of the screen with Welcome back, Sara! Lessons done: 3 in its bottom-left corner
Sara's welcome banner

Read the nesting from the outside in: space around the banner (Padding) → keep it at the top (Align) → give it a 2 : 1 shape (AspectRatio) → paint it (ColoredBox) → space inside it (Padding) → put the text bottom-left (Align). Each widget does one small job.

Colors.teal.shade100 is a light shade of teal. Every color in Colors has shades from 50 (lightest) to 900 (darkest). Because shade100 is calculated when the app runs, the ColoredBox around it cannot be const — the editor will not let you write const there.


Code Examples

Example 1 — Padding on Every Side

dart
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 Padding(
        padding: EdgeInsets.all(32),
        child: Text('Padding pushes content away from the edges.'),
      ),
    );
  }
}
A sentence indented 32 pixels from the left and top
Example 1

Example 2 — Different Padding per Side

fromLTRB reads left, top, right, bottom. The amber area shows exactly where the padding went.

dart
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: const Center(
        child: ColoredBox(
          color: Colors.amber,
          child: Padding(
            padding: EdgeInsets.fromLTRB(8, 24, 48, 4),
            child: Text('fromLTRB(8, 24, 48, 4)'),
          ),
        ),
      ),
    );
  }
}
A centered amber label whose padding is narrow on the left, wide on the right
Example 2

Example 3 — A Hint at the Bottom of the Screen

Align pins the text to the bottom; EdgeInsets.only(bottom: 48) lifts it off the edge.

dart
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: const Align(
        alignment: Alignment.bottomCenter,
        child: Padding(
          padding: EdgeInsets.only(bottom: 48),
          child: Text('Swipe up to continue'),
        ),
      ),
    );
  }
}
The text Swipe up to continue near the bottom center
Example 3

Example 4 — Student Report Box

dart
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 = 'Ali';
    int total = 240;

    return Scaffold(
      appBar: AppBar(title: const Text('Student Report')),
      body: Center(
        child: SizedBox(
          width: 220,
          height: 80,
          child: ColoredBox(
            color: Colors.blue.shade100,
            child: Center(child: Text('$name: $total / 300')),
          ),
        ),
      ),
    );
  }
}
A light blue 220 by 80 box in the center with Ali: 240 / 300
Example 4

Example 5 — Shopping Total That Always Fits

The box is three times wider than tall; FittedBox makes the total fill it.

dart
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) {
    int total = 1250;

    return Scaffold(
      appBar: AppBar(title: const Text('Shopping Cart')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: AspectRatio(
          aspectRatio: 3,
          child: ColoredBox(
            color: Colors.green.shade100,
            child: FittedBox(child: Text('Total: Rs. $total')),
          ),
        ),
      ),
    );
  }
}
A wide light green box with Total: Rs. 1250 in large text
Example 5

Example 6 — Bank Card

A real bank card is about 1.6 times wider than tall.

dart
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 CardScreen(),
    );
  }
}

class CardScreen extends StatelessWidget {
  const CardScreen({super.key});

  @override
  Widget build(BuildContext context) {
    String owner = 'Zayan';
    double balance = 25000;

    return Scaffold(
      appBar: AppBar(title: const Text('Bank Card')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: AspectRatio(
          aspectRatio: 1.6,
          child: ColoredBox(
            color: Colors.indigo.shade100,
            child: Padding(
              padding: const EdgeInsets.all(20),
              child: Align(
                alignment: Alignment.bottomLeft,
                child: Text('$owner · Rs. $balance'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
An indigo card shape with Zayan · Rs. 25000.0 in its bottom-left corner
Example 6

Common Beginner Mistakes

1. Giving a single-child widget children

dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: Padding(
          padding: EdgeInsets.all(16),
          children: [Text('Ali'), Text('Sara')],
        ),
      ),
    ),
  );
}
output
error • The named parameter 'children' isn't defined. Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'children' • lib/main.dart:9:11 • undefined_named_parameter

Padding holds exactly one child. To show several widgets you need a multi-child widget such as Column (Lecture 004), and then pad the Column.

2. Passing a number as padding

dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: Padding(padding: 16, child: Text('Hello')),
      ),
    ),
  );
}
output
error • A value of type 'int' can't be assigned to a parameter of type 'EdgeInsetsGeometry' in a const constructor. Try using a subtype, or removing the keyword 'const' • lib/main.dart:7:23 • const_constructor_param_type_mismatch
error • The argument type 'int' can't be assigned to the parameter type 'EdgeInsetsGeometry'.  • lib/main.dart:7:32 • argument_type_not_assignable

padding needs an EdgeInsets: padding: EdgeInsets.all(16).

3. Wrong capitalization of an Alignment name

dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: Align(alignment: Alignment.topleft, child: Text('Hello')),
      ),
    ),
  );
}
output
error • Invalid constant value • lib/main.dart:7:32 • invalid_constant
error • The getter 'topleft' isn't defined for the type 'Alignment'. Try importing the library that defines 'topleft', correcting the name to the name of an existing getter, or defining a getter or field named 'topleft' • lib/main.dart:7:42 • undefined_getter

The names use lowerCamelCase: topLeft, bottomRight, centerLeft.

4. Forgetting the parameter name

dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: Padding(EdgeInsets.all(16), child: Text('Hello')),
      ),
    ),
  );
}
output
error • The named parameter 'padding' is required, but there's no corresponding argument. Try adding the required argument • lib/main.dart:7:15 • missing_required_argument
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:23 • extra_positional_arguments_could_be_named

Flutter widgets use named parameters. Write padding: EdgeInsets.all(16), not just EdgeInsets.all(16).


Best Practices

  • Use Padding (or SizedBox gaps) instead of spaces inside strings to create room.
  • Pick spacing from a small set of values — 4, 8, 16, 24, 32 — and reuse them, so screens look consistent.
  • Reach for Center when you want the middle and Align for everything else.
  • Prefer AspectRatio over fixed heights for banners and pictures, so they look right on every phone width.
  • When a layout surprises you, wrap the widget in a ColoredBox to see its real size.

Mini Challenge

Build a temperature banner for Lahore. Store city = 'Lahore' and celsius = 30. The banner:

  • sits at the top of the screen, 16 pixels from the edges
  • has a 16 : 9 shape and a light orange color (Colors.orange.shade100)
  • has 24 pixels of space inside it
  • shows Lahore 30°C scaled up to fill the space

Try it yourself before opening the solution.

Show solution
dart
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.orange),
      home: const TemperatureScreen(),
    );
  }
}

class TemperatureScreen extends StatelessWidget {
  const TemperatureScreen({super.key});

  @override
  Widget build(BuildContext context) {
    String city = 'Lahore';
    int celsius = 30;

    return Scaffold(
      appBar: AppBar(title: const Text('Temperature')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Align(
          alignment: Alignment.topCenter,
          child: AspectRatio(
            aspectRatio: 16 / 9,
            child: ColoredBox(
              color: Colors.orange.shade100,
              child: Padding(
                padding: const EdgeInsets.all(24),
                child: FittedBox(child: Text('$city $celsius°C')),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
A light orange 16-to-9 banner at the top with Lahore 30°C in large text
Mini challenge solution

How it works

  1. Padding keeps the banner 16 pixels from the screen edges.
  2. Align(alignment: Alignment.topCenter) lets the banner keep its own height instead of filling the screen.
  3. AspectRatio(16 / 9) works out the height from the width.
  4. The inner Padding leaves room inside the color, and FittedBox scales the text up.

Practice Questions

Beginner

  1. Show the text Hello with 32 pixels of padding on every side.
  2. Show v1.0 in the top-right corner with 8 pixels of padding.
  3. Show an amber square of 150 × 150 in the center of the screen.

Application

  1. Indent the text Indented text 40 pixels from the left and 80 from the top using EdgeInsets.only.
  2. Show a green square that is as wide as the screen minus 16 pixels on each side (use AspectRatio).
  3. Store celsius = 30 and show Today: 30°C at the bottom center, 40 pixels above the edge.
  4. Make the text Total: Rs. 1,250,000 fit inside a 120 × 40 box in the center.

Challenge

  1. Store name = 'Ali' and total = 240. Build a card at the top of the screen, 16 pixels from the edges, with a 2 : 1 shape, the color Colors.blue.shade50, and the text Ali — 240/300 centered inside it.

Practice Answers

Question 1 — Solution

dart
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 Padding(padding: EdgeInsets.all(32), child: Text('Hello')),
    );
  }
}
Hello indented 32 pixels from the top-left
Question 1

Question 2 — Solution

dart
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: const Align(
        alignment: Alignment.topRight,
        child: Padding(padding: EdgeInsets.all(8), child: Text('v1.0')),
      ),
    );
  }
}
v1.0 in the top-right corner
Question 2

Question 3 — Solution

A SizedBox with a ColoredBox child: the box gives the size, the ColoredBox makes it visible.

dart
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 Center(
        child: SizedBox(
          width: 150,
          height: 150,
          child: ColoredBox(color: Colors.amber),
        ),
      ),
    );
  }
}
An amber square in the center
Question 3

Question 4 — Solution

dart
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: const Padding(
        padding: EdgeInsets.only(left: 40, top: 80),
        child: Text('Indented text'),
      ),
    );
  }
}
Indented text placed 40 pixels from the left and 80 from the top
Question 4

Question 5 — Solution

dart
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: AspectRatio(
          aspectRatio: 1,
          child: ColoredBox(color: Colors.green),
        ),
      ),
    );
  }
}
A large green square near the top with a 16-pixel margin
Question 5

Question 6 — Solution

dart
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 WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatelessWidget {
  const WeatherScreen({super.key});

  @override
  Widget build(BuildContext context) {
    int celsius = 30;

    return Scaffold(
      appBar: AppBar(title: const Text('Question 6')),
      body: Align(
        alignment: Alignment.bottomCenter,
        child: Padding(
          padding: const EdgeInsets.only(bottom: 40),
          child: Text('Today: $celsius°C'),
        ),
      ),
    );
  }
}
Today: 30°C near the bottom center
Question 6

Question 7 — Solution

This time FittedBox shrinks the text, because it is wider than 120 pixels.

dart
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 BillScreen(),
    );
  }
}

class BillScreen extends StatelessWidget {
  const BillScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Question 7')),
      body: const Center(
        child: SizedBox(
          width: 120,
          height: 40,
          child: FittedBox(child: Text('Total: Rs. 1,250,000')),
        ),
      ),
    );
  }
}
Small text Total: Rs. 1,250,000 in the center
Question 7

Question 8 — Solution

dart
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 MarksScreen(),
    );
  }
}

class MarksScreen extends StatelessWidget {
  const MarksScreen({super.key});

  @override
  Widget build(BuildContext context) {
    String name = 'Ali';
    int total = 240;

    return Scaffold(
      appBar: AppBar(title: const Text('Question 8')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Align(
          alignment: Alignment.topCenter,
          child: AspectRatio(
            aspectRatio: 2,
            child: ColoredBox(
              color: Colors.blue.shade50,
              child: Center(child: Text('$name — $total/300')),
            ),
          ),
        ),
      ),
    );
  }
}
A pale blue 2-to-1 card at the top with Ali — 240/300 in the center
Question 8

Quick Revision

  1. What is the difference between child and children?
  2. Which EdgeInsets constructor sets only the sides you name?
  3. What is Center a special case of?
  4. Where is Alignment(1, 1)?
  5. What does SizedBox(height: 16) with no child do?
  6. How does AspectRatio decide the height?
  7. Does FittedBox only make things smaller?
  8. Complete the rule: constraints go ___, sizes go ___.

Key Takeaways

  • Single-child layout widgets take one child and change its position, size or spacing.
  • Padding + EdgeInsets (all, symmetric, only, fromLTRB) adds space around a child.
  • Align + Alignment puts a child anywhere; Center is Align at the center.
  • SizedBox gives an exact size — or an empty gap when it has no child.
  • AspectRatio keeps a width : height shape; FittedBox scales a child to fit.
  • A parent passes constraints down; the child picks a size within them.

What's Next?

Lecture 003 — Container & Styling. Our boxes so far are flat colored rectangles. Next we meet Container — padding, margin, size and color in one widget — and BoxDecoration for rounded corners, borders, shadows and gradients, plus TextStyle to finally change how text looks.