Mobile App Development with Flutter
Chapter 3 / 7· 22 min read· 0 cards

Flutter Widgets: Everything is a Widget

The core of Flutter — how widgets compose to build any interface.

The widget is everything

Now we reach the heart of Flutter. As mentioned, everything you see on screen is a widget — text, buttons, images, layouts, padding, even the app itself. You build your entire interface by creating widgets and nesting them inside one another. Understanding widgets deeply is understanding Flutter. Let's build that understanding from the ground up.

Your first widget

A widget is a Dart class that describes part of the UI. The simplest widgets just display something — like Text, which shows a string. Here's a minimal Flutter app, which is itself made entirely of widgets:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("Hello, Flutter!"),
        ),
      ),
    ),
  );
}

Look at the nesting — it's widgets all the way down. MaterialApp wraps the whole app, Scaffold provides the basic screen structure, Center centres its child, and Text displays the message. Each is a widget containing another widget via the child (or home, body) property. This nesting — the "widget tree" — is how every Flutter UI is built.


The widget tree

Flutter arranges widgets into a tree, with each widget having children, forming the structure of your UI. Visualising this tree is key to understanding any Flutter screen:

  MaterialApp              (the whole app)
    └─ Scaffold            (a screen's structure)
        └─ Center          (centres its child)
            └─ Text        (displays "Hello, Flutter!")

  Each widget wraps the one below it.
  You build UIs by composing this tree.

This compositional model is powerful: complex interfaces are just trees of simple widgets nested together. It's the same idea as React components nesting (from our React course) — small pieces combined into a whole. Once you think in terms of the widget tree, building any layout becomes a matter of choosing and nesting the right widgets.


Stateless widgets: your own reusable components

You don't just use built-in widgets — you create your own by extending Flutter's widget classes. The most basic kind is a StatelessWidget: a widget that displays something based on the information given to it, and doesn't change on its own. You create one by extending StatelessWidget and implementing its build method, which returns the widget tree to display:

import 'package:flutter/material.dart';

// Our own reusable widget
class Greeting extends StatelessWidget {
  final String name;

  // Constructor receiving data (like props in React)
  const Greeting({required this.name});

  @override
  Widget build(BuildContext context) {
    return Text(
      "Hello, $name!",
      style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
    );
  }
}

// Use it like any widget:
// Greeting(name: "Mehul")

This is exactly like building a reusable component. The build method returns what to show; the final String name is data passed in (similar to props); and you use Greeting(name: "Mehul") wherever you need it. Notice the named parameter name: — that's the Dart feature from the last chapter, used everywhere in Flutter. The @override marks that we're providing our own build, replacing the parent's.


Common display widgets

Flutter provides a rich library of ready-made widgets. A few you'll use constantly for displaying content:

// Text — display a string, with styling
Text("Hello", style: TextStyle(fontSize: 20, color: Colors.blue))

// Icon — a built-in icon
Icon(Icons.favorite, color: Colors.red)

// Image — display an image from the web
Image.network("https://example.com/photo.jpg")

// ElevatedButton — a tappable button
ElevatedButton(
  onPressed: () { print("Tapped!"); },   // what happens on tap
  child: Text("Click me"),
)

Each widget is configured through its parameters — Text takes the string and a style, Icon takes which icon and a colour, the button takes an onPressed function and a child to display. You compose these into your screens. Notice the button's onPressed takes a function — that's how widgets respond to interaction, which we'll build on later.


The Material Design library

You'll have noticed import 'package:flutter/material.dart' at the top and widgets like MaterialApp and Scaffold. Flutter comes with Material Design — Google's design system — giving you a complete set of polished, professional-looking widgets (buttons, app bars, cards, navigation) out of the box. This is a big reason Flutter apps look good easily: you're building with well-designed components from the start. (There's also a Cupertino library that mimics iOS's look, but Material is the common starting point.)

You now understand the fundamental concept of Flutter — widgets composing into trees — and can create your own. But a screen needs more than single widgets stacked up; it needs layout: arranging things in rows, columns, and with spacing. That's the next chapter, where your UIs really start to take shape.

Reading mode · scroll to read at your own pace

Finished "Flutter Widgets: Everything is a Widget"?

Mark this chapter complete so you can pick up exactly where you left off. Your progress saves locally — sign in to sync across devices.

Was this chapter clear?

Try it yourself — open the Code Playground15+ languages — Python, JavaScript, Java, C++, SQL & more — full IDE-style editor, instant run. Your code is auto-saved per language.