Chapters

Hide chapters

Flutter Apprentice

Fourth Edition · Flutter 3.16.9 · Dart 3.2.6 · Android Studio 2023.1.1

Section II: Everything’s a Widget

Section 2: 5 chapters
Show chapters Hide chapters

Section IV: Networking, Persistence & State

Section 4: 6 chapters
Show chapters Hide chapters

4. Understanding Widgets
Written by Vincent Ngo

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You may have heard that everything in Flutter is a widget. While that might not be absolutely true, most of the time when you’re building apps, you only see the top layer: widgets. In this chapter, you’ll dive into widget theory. You’ll explore:

  • Widgets
  • Widget rendering
  • Flutter Inspector
  • Types of widgets
  • Widget lifecycle

It’s time to jump in!

Note: This chapter is mostly theoretical. You’ll make just a few code changes to the project near the end of the chapter.

What Is a Widget?

A widget is a building block for your user interface. Using widgets is like combining Legos. Like Legos, you can mix and match widgets to create something amazing.

Flutter’s declarative nature makes it super easy to build a UI with widgets. A widget is a blueprint for displaying the state of your app.

UI = f Screen Build ( state )

You can think of widgets as a function of UI. Given a state, the build() method of a widget constructs the widget UI.

Unboxing CategoryCard

In the previous chapter, you created three cards. Now, you’ll look at the widgets that compose CategoryCard in more detail:

Widget Trees

Every widget contains a build() method. In this method, you create a UI composition by nesting widgets within other widgets. This forms a tree-like data structure. Each widget can contain other widgets, commonly called children. Below is a visualization of CategoryCard’s widget tree:

Tebeml Wekj KutulaxtWuwy luokx() tuudb() viewd() Faur Linlan Vrawj fiixp() MetvTevu yuijs() Vong Macb zeosg() ZwikQRipx zooby() Nofumeeruh Jeriwuudab Uguga liebn() veint() Rocs FunukilSas Qemw

Rendering Widgets

In Chapter 1, “Getting Started,” you learned that Flutter’s architecture contains three layers:

Oxzoncun (Bruypuys-kqiyabug) Psacukips (Satj) Udfiqa (P/B++)

Xuatguquem Dimhoxekq Kelpogw Fayefeej og Jetemyuli

Three Trees

Flutter’s framework actually manages not one, but three trees in parallel:

PaiMufped Tofleph Yicxovecojiib Epacacw Quperfxno halapusijb Zofc blofafsiuy Huxkij URU PeoUvunapy Jemuru dizohexbus ivt aqirurx ftia Legsoxubby a Goggaf ex o rgua NozwoqIhwakh Gaidb Nlerv hut lu cihi asf yuock Hoyoix Ngodxyod Tupkan juy anlib, lug-fizbajf SawharYae

Types of Elements

There are two types of elements:

Example Trees for CategoryCard

The image below shows an example of the three trees for the CategoryCard widget:

Pebhav Bqae Elenifz Qtia CutvavEmxomw Kgai PoyusuxkKuzf Taqh Dugexg Hgomz DeqvTiow ZxelukutbUrowupz HqamabophIcenumn ZcawonoydEhumazs KocroyIyquxy KoxxuhTpux VurjisOqmewk

Getting Started

Open the starter project in Android Studio, run flutter pub get if necessary, and then run the app. You’ll see the Yummy app from the previous chapter:

DevTools Overview

DevTools provides all kinds of awesome tools to help you debug your Flutter app. These include:

Flutter Inspector

The Flutter Inspector has four key benefits. It helps you:

Flutter Inspector Tools

Here are some of the important tools to use with the Flutter Inspector.

Inspecting the Widget Tree

In the emulator, select the first tab, then click Refresh Tree in the DevTools. Finally, select CategoryCard and click Widget Details Tree tab, as shown below:

Inspecting Like a Pro

Besides checking the properties in Details Tree, you can evaluate your widgets in two other ways:

Layout Explorer

Next, click the Layout Explorer tab, as shown below:

Learning the Types of Widgets

There are three major types of widgets: Stateless, Stateful and Inherited. All widgets are immutable, but some have a state attached to them using their element. You’ll learn more about the differences between these next.

Stateless Widgets

The state or properties of a stateless widget can’t be altered once it’s built. When your properties don’t need to change over time, it’s generally a good idea to start with a stateless widget.

Zdacaqitc Setnisw Govasznli haicy(woxguvk)() qimjcyulpud

Stateful Widgets

Stateful widgets preserve state, which is useful when parts of your UI need to change dynamically.

Wharudum Sefqonz Vajesqxsi xmaoyeCgiri() wiqyphubtat

State Object Lifecycle

Every widget’s build() method takes a BuildContext as an argument. The build context tells you where you are in the tree of widgets. You can access the element for any widget through the BuildContext. Later, you’ll see why the build context is important, especially for accessing state information from parent widgets.

noxKbizdiZodobqifriic ejelFsizo buqfh = qqoi WauhjRaswukd ujmalxal yoaql wuqwp = fazwo foxkuga leodzarive jobUgfekaBuhfaw fayPfuju abnMoydul szebe ppuzsew yiihbop = vwuu hiufyay = lehho penhub.rquvulteuf

Adding Stateful Widgets

class RestaurantLandscapeCard extends StatefulWidget {
  ...

  @override
  State<RestaurantLandscapeCard> createState() =>
    _RestaurantLandscapeCardState();
}

class _RestaurantLandscapeCardState extends State<RestaurantLandscapeCard> {
  // TODO: Add _isFavorited property
  @override
  Widget build(BuildContext context) {
    ...
  }

Implementing Favorites

In _RestaurantLandscapeCardState, find // TODO: Add _isFavorited property and replace it with the following property:

bool _isFavorited = false;
// 1
child: Stack(
  fit: StackFit.expand,
  children: [
    // 2
    Image.asset(
      widget.restaurant.imageUrl,
      fit: BoxFit.cover,
    ),
    // 3
    Positioned(
      top: 4.0,
      right: 4.0,
      child: IconButton(
        // 4
        icon: Icon(_isFavorited
            ? Icons.favorite  //
            : Icons.favorite_border,
          ),
        iconSize: 30.0,
        color: Colors.red[400],
        // 5
        onPressed: () {
          setState(() {
            _isFavorited = !_isFavorited;
          });
        },
      ),
    ),
  ],
)

Examining the Widget Tree

Now that you’ve turned RestaurantLandscapeCard into a stateful widget, your next step is to look at how the element tree manages state changes.

QoxteabiytHiqctpire Tigg Osoy (♡) Hekviq Fmae Omotojq Dguu Wpimogoh Oyawulv Bfoxocoqs Ayicakx Xlafe (_ebWecezozox = racge)

QonyoulaffQabfxcaza Tusw Tibjov Ryai Oguxeqq Stoi Qhumilob Urafokb Wsowafucp Esasebx Lyaye (_uyVofuhesos = mdee) kajry! Anog (♥) xid Ocof berjod ofllesso Moq gi gofimuye

GesroemakpYugmvfika Fidd Fozdad Wvou Apiradk Yrie Vqopiboh Ifevegr Nsexizajx Iladoxm Vhimi (_exFirageruz = bqou) Coq vo sekalego nwioj Iyec (♥)

Inherited Widgets

Inherited widgets let you access state information from the parent elements in the tree hierarchy.

Xihdoz Jogmay Totnab Povnul Citqor Tebjab Titbuh Zaspic Zowcih Vasjog Lesfic Batgej Tocbit Bewkiy Purmud Mebrip Hafzum UjyacodudMiscus Hilfen Yuzruv Hozcow Btupitio 6 Lrovohea 2 Kuhe

Key Points

  • Flutter maintains three trees in parallel: the Widget, Element and RenderObject trees.
  • A Flutter app is performant because it maintains its structure and only updates the widgets that need redrawing.
  • The Flutter Inspector is a useful tool to debug, experiment with and inspect a widget tree.
  • You should always start by creating StatelessWidgets and only use StatefulWidgets when you need to manage and maintain the state of your widget.
  • Inherited widgets are a good solution to access state from the top of the tree.

Where to Go From Here?

If you want to learn more theory about how widgets work, check out the following links:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now