Flutter Fundamentals
Irbisa · cheatsheetSeptember 13, 2026

Flutter Fundamentals

Widget tree, StatelessWidget, StatefulWidget, BuildContext

Junior Developer20 itemscompressed for a skim
  1. 01

    What is Flutter and how does it differ from other cross-platform frameworks?

    Easy

    Flutter is Google's UI toolkit for building natively compiled apps for mobile, web and desktop from a single Dart codebase.

    // Everything in Flutter is a widget composed together
    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
    …
  2. 02

    What is the difference between StatelessWidget and StatefulWidget?

    Easy

    StatelessWidget — immutable description of UI.

    // StatelessWidget — pure function of its inputs
    class GreetingCard extends StatelessWidget {
      final String name;
      final Color color;
      const GreetingCard({super.key, required this.name, this.color = Colors.blue});
    …
  3. 03

    What is BuildContext and why is it important?

    Medium

    BuildContext is a handle to a widget's location in the widget tree.

    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
      @override State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
    …
  4. 04

    In what order do a State object's lifecycle methods run, from creation to disposal?

    Medium

    A StatelessWidget has only a constructor and build(), while a StatefulWidget's State walks a full lifecycle from createState to dispose.

    class RichLifecycleWidget extends StatefulWidget {
      final String config;
      const RichLifecycleWidget({super.key, required this.config});
      @override State<RichLifecycleWidget> createState() => _State();
    }
    …
  5. 05

    What is the difference between hot reload, hot restart, and full restart?

    Easy

    Hot reload injects new code and keeps app state, hot restart resets the Dart VM and all state, and a full restart rebuilds and reinstalls the app.

    class _CounterState extends State<Counter> {
      int _count = 0;                  // survives hot reload, reset by hot restart
    
      @override
      void initState() {
        super.initState();
    …
  6. 06

    What is MediaQuery and how do you build responsive layouts?

    Medium

    MediaQuery provides information about the device screen: size, pixel ratio, text scale, padding (safe area), orientation, and accessibility settings.

    class ResponsivePage extends StatelessWidget {
      const ResponsivePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        // Screen information
    …
  7. 07

    Explain Keys in Flutter and when they are necessary.

    Medium

    Keys give Flutter a stable identity for a widget so that its Element and State survive being reordered or moved.

    // ── Problem: Without keys ──────────────────
    class StatefulTile extends StatefulWidget {
      final String title;
      const StatefulTile(this.title, {super.key});
    
      @override State<StatefulTile> createState() => _StatefulTileState();
    …
  8. 08

    How do you theme a Flutter app and support light and dark mode?

    Medium

    An app's whole look comes from the ThemeData you hand to MaterialApp, and dark mode is a second ThemeData plus a themeMode.

    final _seed = const Color(0xFF6750A4);
    
    final lightTheme = ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: _seed),
      appBarTheme: const AppBarTheme(centerTitle: true),
    );
    …
  9. 09

    How does your app find out that it went to the background, and what should you do there?

    Medium

    A State that mixes in WidgetsBindingObserver gets didChangeAppLifecycleState every time the app moves between foreground and background.

    class _PlayerState extends State<Player> with WidgetsBindingObserver {
      late final VideoController _controller;
    
      @override
      void initState() {
        super.initState();
    …
  10. 10

    What do MaterialApp and Scaffold actually provide, and what breaks without them?

    Easy

    MaterialApp sits once at the root and supplies app-wide machinery, while a Scaffold lays out a single screen.

    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
    …
  11. 11

    A screen fires its API request from inside build() and hammers the server. Why does build run so often, and where does the call belong?

    Medium

    Flutter treats build as a pure function of the widget's inputs and calls it again every time one of them changes, so anything with a side effect must live outside it.

    // ❌ a new request on every rebuild
    @override
    Widget build(BuildContext context) {
      return FutureBuilder(
        future: api.loadUser(widget.id),   // rebuilt = refetched
        builder: (context, snap) => UserView(snap.data),
    …
  12. 12

    Should a long build method be split into private _buildHeader() helpers or into separate widget classes?

    Medium

    A helper method builds into the parent's own element, so its output rebuilds every time the parent does and can never be skipped.

    // ❌ helper method — one Element, rebuilt with the whole page
    class ProfilePage extends StatelessWidget {
      const ProfilePage({super.key});
    
      @override
      Widget build(BuildContext context) => Column(
    …
  13. 13

    A counter is kept as a field on the StatefulWidget itself and setState updates it, but the number keeps resetting. Why?

    Easy

    The widget object holding that field is thrown away and recreated every time the parent builds; only the State survives, so mutable data has to live there.

    // ❌ state on the widget — the field dies with the instance
    class Counter extends StatefulWidget {        // analyzer: must_be_immutable
      Counter({super.key});
      int count = 0;                              // recreated by every parent build
    
      @override
    …
  14. 14

    Why does Flutter make padding, alignment and opacity separate widgets instead of properties that every widget has?

    Easy

    Because composition keeps the framework small: each widget does one job, and the layout you need comes from nesting them rather than from an ever-growing parameter list on everything.

    // Composition: one job per wrapper, and the nesting *is* the layout
    class PriceTag extends StatelessWidget {
      const PriceTag({super.key, required this.label});
      final String label;
    
      @override
    …
  15. 15

    The mobile builds are fine but the web build fails on Platform.isIOS — how should a Flutter app branch on platform?

    Easy

    Platform comes from dart:io, which does not exist on the web, so the import alone breaks the build; Flutter's own answer is kIsWeb and defaultTargetPlatform from package:flutter/foundation.dart.

    // ❌ the web build fails on the import alone, before any code runs
    // import 'dart:io' show Platform;
    // final isApple = Platform.isIOS || Platform.isMacOS;
    
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/foundation.dart';
    …
  16. 16

    The keyboard covers the very field the user is typing in — which MediaQuery values describe that, and what actually fixes it?

    Medium

    The keyboard shows up as MediaQuery.viewInsetsOf(context).bottom, the part of the window the system has covered, and the fix is to hand that space to a scrollable rather than hard-coding heights.

    // A bottom sheet has no Scaffold to resize it — pad by the keyboard yourself
    void showCommentSheet(BuildContext context) {
      showModalBottomSheet<void>(
        context: context,
        isScrollControlled: true,            // otherwise the sheet is capped near half-screen
        builder: (context) => Padding(
    …
  17. 17

    QA reports overlapping text and overflow stripes only on devices with the largest system font — how do you handle text scaling?

    Medium

    The OS font-size setting scales every Text through MediaQuery.textScalerOf(context), so any box with a hard-coded height and any row of long labels breaks somewhere between 150% and 200%.

    // Cap scaling once, at the root — generously, and never at 1.0
    final app = MaterialApp(
      builder: (context, child) {
        final scaler = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: 1.4);
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaler: scaler),
    …
  18. 18

    You push a details screen and the list behind it keeps polling the API — what happened to that screen's State when the new route covered it?

    Medium

    Nothing was disposed: Navigator keeps the covered route in the Overlay, so its State stays alive with dispose unrun — only its tickers are muted and its render subtree is skipped.

    import 'dart:async';
    import 'package:flutter/material.dart';
    
    // Registered once, on the app
    final routeObserver = RouteObserver<ModalRoute<void>>();
    …
  19. 19

    Testers say the app returns to a blank form after sitting in the background for a while on Android — what does Flutter offer for that?

    Medium

    Android killed the process while it was backgrounded and Flutter relaunched from main(); the built-in answer is the state restoration framework, which parks small pieces of UI state with the OS and hands them back on relaunch.

    import 'package:flutter/material.dart';
    
    // Nothing below is restored without this scope on the app
    final app = MaterialApp(
      restorationScopeId: 'app',
      home: const Cart(),
    …
  20. 20

    Product wants the app in Spanish next sprint and every string is hardcoded in the widgets — what does Flutter give you natively for that?

    Medium

    Flutter's own path is flutter_localizations plus the gen-l10n generator: strings live in ARB files, the tool generates an AppLocalizations class, and widgets read it out of the tree with AppLocalizations.of(context).

    // l10n.yaml at the project root
    //   arb-dir: lib/l10n
    //   template-arb-file: app_en.arb
    //   output-localization-file: app_localizations.dart
    
    // lib/l10n/app_en.arb — ICU plurals live in the data, not in Dart
    …