Basic Widgets
Irbisa · cheatsheetSeptember 13, 2026

Basic Widgets

Core layout widgets: Container, Row, Column, Stack, ListView

Junior Developer20 itemscompressed for a skim
  1. 01

    What is the difference between Container, SizedBox, Padding, and ColoredBox?

    Easy

    SizedBox, Padding and ColoredBox each do exactly one job; Container is a convenience wrapper that composes several of them at once.

    // ── Lightweight options (prefer these) ────────────
    const SizedBox(width: 16, height: 16)  // spacer
    const SizedBox.expand()                 // fills available space
    const SizedBox.shrink()                 // 0×0 invisible
    
    Padding(
    …
  2. 02

    Explain Row, Column, and Stack with their key properties.

    Easy

    Row lays its children out horizontally, Column vertically, and Stack overlaps them along the z-axis.

    // Row
    Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const Icon(Icons.star, color: Colors.amber),
    …
  3. 03

    What is the difference between ListView, GridView, and CustomScrollView?

    Medium

    ListView scrolls along a single axis, GridView lays out a scrollable 2D grid, and CustomScrollView stitches several sliver areas into one coordinated scroll.

    // ListView.builder — for any dynamic list
    ListView.builder(
      itemCount: items.length,
      itemExtent: 72.0,  // ✅ fixed height enables fast scrolling
      itemBuilder: (context, index) => ListTile(
        leading: CircleAvatar(child: Text('${index + 1}')),
    …
  4. 04

    How do you handle forms and validation in Flutter?

    Medium

    A Form widget plus a GlobalKey<FormState> coordinates validation and saving across every field inside it.

    class LoginForm extends StatefulWidget {
      const LoginForm({super.key});
      @override State<LoginForm> createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
    …
  5. 05

    How does CustomPainter work and when would you use it?

    Hard

    CustomPainter gives you direct access to a Canvas to draw anything — shapes, paths, gradients, charts — that built-in widgets cannot achieve.

    class PieChartPainter extends CustomPainter {
      final List<double> values;
      final List<Color> colors;
    
      PieChartPainter({required this.values, required this.colors});
    …
  6. 06

    What is the difference between Expanded and Flexible widgets?

    Medium

    Expanded is the tight form of Flexible — it forces its child to fill exactly the space it was allotted.

    // ── Basic Expanded ─────────────────────────
    Row(
      children: [
        Expanded(
          child: Container(color: Colors.red),
        ),
    …
  7. 07

    How does LayoutBuilder work and when should you use it?

    Medium

    LayoutBuilder provides parent constraints to build child widgets responsively.

    // ── Basic LayoutBuilder ────────────────────
    LayoutBuilder(
      builder: (context, constraints) {
        print('Max width: ${constraints.maxWidth}');
        print('Max height: ${constraints.maxHeight}');
    …
  8. 08

    What are the Material 3 button widgets and when do you pick each?

    Easy

    Material 3 ships five button styles, each with a specific role on the page.

    // Primary action — only one per screen
    FilledButton(
      onPressed: _signUp,
      child: const Text('Create account'),
    );
    …
  9. 09

    How do you display images in Flutter — assets, network, memory, file?

    Easy

    Flutter's Image widget renders any image source via constructors that match the input.

    // Asset — instant, bundled
    Image.asset('assets/logo.png', width: 96, height: 96);
    
    // Declared in pubspec.yaml:
    //   flutter:
    //     assets:
    …
  10. 10

    How do you make an arbitrary widget tappable, and when is InkWell the better choice over GestureDetector?

    Easy

    GestureDetector recognises the gesture but draws nothing, while InkWell adds the Material ripple plus hover and focus feedback.

    GestureDetector(
      behavior: HitTestBehavior.opaque,   // whole box, not just painted pixels
      onTap: _select,
      onLongPress: _showContextMenu,
      child: const Padding(
        padding: EdgeInsets.all(12),
    …
  11. 11

    What is the difference between implicit and explicit animations in Flutter, and which should you reach for first?

    Medium

    An implicit animation interpolates a property for you whenever its value changes, while an explicit one hands you an AnimationController that you drive yourself.

    // ── Implicit: change the value, Flutter tweens it ──
    AnimatedContainer(
      duration: const Duration(milliseconds: 250),
      curve: Curves.easeOut,
      width: _expanded ? 240 : 120,
      padding: EdgeInsets.all(_expanded ? 24 : 8),
    …
  12. 12

    Putting a ListView inside a Column throws a layout error. What causes it and what are the fixes?

    Medium

    A Column gives its children unbounded height on the main axis, and a ListView tries to fill whatever height it is given, so together they produce an infinite constraint.

    // ❌ Vertical viewport was given unbounded height
    Column(
      children: [
        const ProfileHeader(),
        ListView.builder(itemCount: items.length, itemBuilder: _row),
      ],
    …
  13. 13

    A row of tag chips overflows with yellow stripes as soon as the tags get long — which widget fixes it, and what does it cost?

    Easy

    Wrap lays children out on one run until the line is full, then starts a new run; a Row has exactly one line and overflows instead.

    // ❌ Row has one line — RenderFlex overflowed by 68 pixels
    Row(
      children: [for (final t in tags) Chip(label: Text(t))],
    );
    
    // ✅ Wrap starts a new run when the line is full
    …
  14. 14

    The bottom bar sits on top of the iPhone home indicator, and sprinkling SafeArea everywhere leaves double gaps — how does SafeArea actually work?

    Easy

    SafeArea is a Padding that reads MediaQuery.padding, insets its child by it, and then hands down a MediaQuery with that padding removed — which is why a nested SafeArea adds nothing and why the order of widgets around it matters.

    // The AppBar already consumed the status bar — top: false avoids a second gap
    Scaffold(
      appBar: AppBar(title: const Text('Inbox')),
      body: SafeArea(
        top: false,
        child: ListView(children: rows),
    …
  15. 15

    You set width: 300 on a Container and it still fills the whole screen. What layout rule explains that, and how do you actually get 300?

    Medium

    The parent's constraints win: a widget may only choose a size the constraints allow, and a tight constraint allows exactly one.

    // ❌ width ignored: the Scaffold body gives its child tight constraints
    Scaffold(
      body: Container(width: 300, color: Colors.teal), // fills the screen
    );
    
    // ✅ Center loosens them, so the child may pick a smaller size
    …
  16. 16

    A notification badge positioned at the corner of an avatar is half cut off, and the visible half ignores taps. What is going on?

    Medium

    A Stack clips to its own box and never hit-tests outside it, so whatever a Positioned pushes past the edge is trimmed when painting and dead to pointers either way.

    // ❌ half the badge is clipped, and the half you can see is not tappable
    Stack(
      children: [
        const Avatar(size: 48),
        Positioned(
          top: -6,
    …
  17. 17

    Grid tiles print BOTTOM OVERFLOWED BY 14 PIXELS on a tester's phone but look perfect on yours. What decides a tile's height?

    Medium

    The grid delegate decides it, from the column width and childAspectRatio — the content never gets a vote, because each tile is laid out with tight constraints.

    // ❌ height is derived from the width; 1.3x text scale blows the tile apart
    GridView.builder(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 12,
        mainAxisSpacing: 12,
    …
  18. 18

    A login form throws "A RenderFlex overflowed by 137 pixels" the moment the keyboard opens. What is the right fix?

    Medium

    The keyboard shrinks the Scaffold body and a Column has nowhere to put the extra content, so the content has to become scrollable.

    // ❌ overflows the moment the keyboard halves the body
    Scaffold(
      body: Column(
        children: const [Logo(), EmailField(), PasswordField(), SubmitButton()],
      ),
    );
    …
  19. 19

    A reviewer flags IntrinsicHeight as expensive. What does it actually do at layout time, and when is it still the right call?

    Hard

    It runs a speculative measurement pass over its subtree to ask how tall the children would like to be, and only then lays them out — so that subtree is walked twice, and the cost compounds with nesting.

    // ✅ legitimate: the divider must match the taller card, whose height
    //    nobody knows until the text is laid out
    IntrinsicHeight(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: const [
    …
  20. 20

    An expanded row in a long ListView collapses itself after you scroll it off screen and back. Why, and what do you do about it?

    Hard

    ListView.builder unmounts any item that scrolls past the cache window and disposes its State, so anything the row kept in its own State is gone by the time it comes back.

    // ❌ the flag lives in the row's State, which is disposed on scroll-off
    class _ExpandableRowState extends State<ExpandableRow> {
      bool _open = false; // gone the moment the row leaves the cache window
    }
    
    // ✅ 1. hoist it — the row is stateless again and the list stays lazy
    …