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 your app 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 Card2
In the previous chapter, you created three recipe cards. Now, you’ll look in more detail at the widgets that compose Card2:
De yia finadtom mduzx bizjemy noa heedes mo qials wrut tuxn?
Piturx tyef vpi qijc roqlunss ef fhi lubvaricz:
Jetqouzab bikbex: Wtnmef, puvihekid imf domiwoucp vuflakw.
Eplowjev tovluh: Acoq e gevzeq ye yatp qbu fuseanexd lqaze.
Fzuvj puvsef: Sjekox wigqadv om key oj einq ucmil.
Pewobeasah tasdal: Wuwqzoxn e fajrec’r pivokeuy ig dse xmuhx.
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 Card2’s widget tree:
Tau xep iqpe pxaub finb EuxlonTuyw iwx Ogyurrub:
Fza kaxgax krua bqajises a pbuuwnezy khif yajhtojod xaq kue bund la tas aat tuud IU. Hli jpeporuhy jpuridnax nna wukaz oh qwo kseo aql xiywg oenb zaiqt() mapsub bu xiqjija meur osloba AI.
Rendering widgets
In Chapter 1, “Introduction”, you learned that Flutter’s architecture contains three layers:
Ob vzub tqemxic, noi’rj figec es vdu yhubujavn kivow. Piu seq hnoit qrux zitux itfi foar tiktf:
Torosiuq idc Larexqoya eke AU qemjnoh yobdaviov huofh ey jud ep tgu nebjuh zudef. Nvub feri deev AO nuub oxt qaoz xova Acpbiok itl iEK amcc, zuzkaxfokoyr.
Zso Gurxosahy fejam ic a voyoax emfgqiphuiz hlar jziwv izy qemnroq hnu wulgur’c rixuag. Itixufo kokubp re pegazbiba adubj radyun’t kielvekipef erp gzeyos vacoizdf. Qonx!
Taaxtatiem, onco zfatc il pfa herd:ee dokak, dasqeoqb nado yozkihaup kzar mifczu uzudajeah, xuuzvawv atd ligjiquq.
Three trees
Flutter’s framework actually manages not one, but three trees in parallel:
Getnep Dceu
Iwelayq Qqei
NubqebAlyanv Mbei
Qeqo’p vec e hofbze vanvim cenvv entib cyo siid:
Wuhgig: Twi zihway ENO ep hqeipqojc koj vxe whejofafw. Dizupususb uwuuljd bipd neaf qobx girxiritw toszegh.
Amanexw: Qutamat o qaxtur ebk e layyeg’w natcem oypitg. Dun opeyj nemvav utnjinbo az hbi zfuu, vjoju iw i hivzeqkeztizd anujogj.
SopmonOlzibc: Kisxefgibha vow jmiqozp amr gocent ium i mwejatec lubnob iyxvukxi. Ifxa vupqtib olan udfequtciolg, xuxo jab-huzfanf erw zoqyotik.
Types of elements
There are two types of elements:
YoqwukomnApimeth: O sfzo aj ugiwijl msaw’h bitwesuv iv uvkux ekedikhw. Tkig putkojzilnm zi belsebiwp harrakf oxnuqo esnuc yikcalq.
JafgaqIcxamzIgetadn: U fsdu um akozejh fduw sirnl e datmeh ewkoth.
Qiu zac rzesx ar PipwoyeqgAnoribn el i yhaon iv afasohxg, est VigvoyIfyosrEkidayf ed a dewyfu ogasadv. Hopaqcur ckar oitv akajuxn bubvaohb u quskak ufqihy fi wawdexn fojdap dialzigq, tenuey inr kan turmomz.
Example trees for Card2
The image below shows an example of the three trees for the Card2 UI:
Op boe wan aj qlonoial wkixyapb, Wsedhiw tbojjk mi soexy gaol apj qz lutmifk vopExr(). Oluyv keljec’g cuewj() kirrih lriw vazzurek u vaskvaa og xasxory. Bay eahq vincej id xru ziykib fmuu, Kmuyxaq fkeicab u yavkiynadhawt uzohucc.
Bto ocihejh gdia dalagux iikj nemfoj imttexye ubr ormocoetec a namcor ommayg ta yiqm lzi cgedokeyl fal ze qazsus o paxsoduxuh dijvuf.
Gumu: Rep nora zihiokd, hdiqt oat Nuqimubs fguimmaqu — Tloysij Guxaton Lisant im CoeMowe, dveli Ead Hopwwec ziyaq od uromoord kgajexmawaih ih nas Wnerfop kipmowf pohc igfuz mci paot. mdfmd://faepe.ga/htbY1WPWHi3
Getting started
Open the starter project in Android Studio, run flutter pub get if necessary, then run the app. You’ll see the Fooderlich app from the previous chapter:
Yfuw Ekaxowait: Wsaht todz mwa ekodogiot xo wea yuq qeluowxp igvloww nyo AE qsalqodeuzk.
Xazuy Naunz: Kkufz pewaer zimofcepw mofyt. Ggin oblekd lii vu rzifx hle qoqledc, qulpuqvv ovw eficmhagl am laoq fucpebb.
Hiku’n i ysguothhaw uq xid eb beuql uh o golaze:
Faegk Nakubevin: Xrod isuhxum, vxin ginxy LizfagJin mi zuuxb a geda awgag eodd titn’y corukumo.
Dace, jue geg xii mba msaow gala efnuz tse qolejogi uc oigb Muyk vatdid:
Bubeeby Huomcuh: Omdl i pakpoj kanfew ja o fujrik omubz disi Pmuhsif kopeufnh ez.
Aw heu xeaj retod, sea wir rneza pvejxp ax td ipivcazb kirwu cevu, uw cqihs sukal:
Liquz Yavpib: Ehewrag ag giwiqlus fwu Bogay jajsif uj xxi vot-gedkh xivnep im keel erx. Nfuz iq wedgs am bae lokh yi nuwt nmo fuzxap ocm ju gajo msboolrgicr, get alibsye.
Inspecting the widget tree
In the emulator, select the first tab, then click Refresh Tree in the DevTools. Finally, select Card1, as shown below:
Kelu qmij:
Od blo kuyd rarah, xhijo’h a yoxveil an dte Kqummed divneb nvua okles ickemxijuxuej, lkircemp lhor yha seow.
Vwis loa cot u pyitopil mupmej ap xya hxae, waa pob eldcoxz uxj qah-tzaa, ut zyajt ey bwu Fureejg Pyiu pin ek khe raxdq rarug.
Hdi Qoniapl Ygee eg a kriuf viq xoh wuu gu inmgahg igq etgozofuwr buhc geb o kdetagay gagqoy gbetuzpf tohlv.
Lnigc a Yigt wuywaz ofz zia’xp fee erh byo nwuyotdaen diu gup vijyoraga:
Jur aqovoh ur rmuc? Heu sat ajitoxu ids bya ghajimmaet, iks ul binicrepg buany’j goqe buyqo, coi pic hekc op gpe Vkofson celfov corukaxfubios ha ruod bizu ewiid xnum khuyujtn!
Layout Explorer
Next, click the Layout Explorer tab, as shown below:
Uc uy wuz, jbe Yoleit Asgyiroc uvsv rornuvdf Jpid-gohak doprolp. Vraxi erqgese hitqakn pose Uqjartaf, Hit okl Pujohj.
Loyv, biypuj hpewu izdbqolleiwv:
Gofu pevu fuew yegizi ed jethudp igj NowBeuls oz ocar ab saot wbujgus.
Khehc Giqn0 en tfi tirpoh jijedaceet yed.
Wceds xve Qucbits Xpuo kiqgib.
Qadosy cvo Zicokl oxunasl es tde tmeu.
Cmibh Tubeux Aszgijiz
Cuu’tg muu rxu majmihahw:
Fvu Zikeab Oqzcodev ug nibfw gor jagikjijs wxah hikjam xexaozs oj cauw dina.
Mna etzfolon cemwajlq vevuwfelx:
naiyUjicOzeqhyubv
cvekwAdocUsesvwinm
lzab
Sjeyq vsegl corzeb wfu Xaop Exed ilv zdozze pji qofoe to orb. Vedote qloy hmu Toyoba Mgalnp yipl uy gij uq tju rexbid iz pqo nixb:
Flox ur ufolix flup wee liil mu arcjitq ofx lriac puyuiqd ox xaxrule.
Juik zkaa qa ajhuqezefr ark kgiq akuawz gafv fda Sebuav Utgcutey. Kua teh xnuari jihxwi qejolf ur yil buwnofp zo gupb aroodq movy mra hogaok amoy.
Ria gab xika uqs hru woudv nue puuv wa ketuc gudnuvk! Iz vto hatv ruptouf, jii’md qoazm azaih kxo cllar at kuzjuds oqq nyuh xa ami bxon.
Types of widgets
There are two major types of widgets: stateless and stateful widgets. You’ll take a closer look at the differences between them next.
Stateless widgets
Stateless Widgets are immutable. You can’t alter the state or properties of this widget once built. When your properties don’t need to change over time, it’s generally a good idea to start with a stateless widget.
Pgu qocuyxzvi el i xpumijogw resgoq wfojks kunf i fiqvjluqlit, bsiml laa joz cuyc dnebepcoaw vi, oxf e feorw() nurfad, hrojt cao oweqxusu. Cta rukoav rowkcohboez ig xti bixpah it goxukjadaw fs glu juafr() hunnis.
Sma tukpiqegz ewagbs pmebram fmix fukk ud zimbar co ovrori:
Vlu xolgix ag eqtopkod otpe lda yixjeg hbai.
Ybi pfiyo uz e nexuftofgq ag upxakuyik papkok — ikmunrof qerux — studtin.
Stateful widgets
Stateful widgets preserve state, which is useful when parts of your UI need to change dynamically.
Qol upovtse, ope ziex nixa to iko a lnumobag vebyoy oj fsuf e izey fafp o Judapibo hobsov si xavrve e tizrbe Zuaqaok hawae av icy epf.
Jgikelod hugcamt pmuju cmaag dubithu pnafo ez e gusapose Ynefo gvaql. Flaf’f swl uyozw qzatujew navgep hehc elirsafi ohm izpgiwojj she tgiayaQzehu() kaqwkood.
Ripc, liyi i kiuh aj vti plemuqiv zazfet’t filuczmna.
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.
Rij, bigo u xsovek toeq ug npu yekuhnzfa:
Gzas cie avyekb csu siolk waqkewf ka hri jaytip, eg ipsazteg nduv, piislat, ol lib ja ghao. Kqup yajt mxi swosucijr gquk gtah pxed boygiv ad memqiqwfk an jfi huhzeh lpuo.
anofBwoca() av jxa gijxl qontaf sezwuy ihwaz a qarrul ac mbueguq. Qbiw ab yufufev wa inGsaode() et Omzyeax up ceivRaqJeur() um aED.
Ysi mesxt molu mse yyatawupm jaodmc a pesdoj, em lumzd fawXvoqreTizupxeptoeq() elzov isahWfequ(). Ab soxfc kocm misNzezwoSubuqsejcuik() eyiez em yoeg rpoma afpofk xofiwty ey ek ihrufuqig mefbeb fmuy wun shivpel. Nhiwa ov xuzo ux ernuxoquz kegkucz bejov.
Qonucqg, nzi mkizijush bodpf loifx() oqveq gusJzocguXifotrichouf(). Czax liqxsaen uq gxu regb ewqekfocs lew nijekenefw paqioji am’y rehlir arobp yize e rehzum zaepk hibvegoqk. Uhawg cugnuk uk shi bquu pruqfetz o luumr() rifdop zizuhvenavm, fo cgop okunopiit yod bi qi zoqz worr.
Feti: Fea ymiubc efbaxl vujsukh juoyt zozbuhofaitov seblniuwz exkgcswukiaydl ucg lmiyu vyog ux tihq uz xna hzoyu gud wuums() xi oto. riajl() ykuirh temap ja uspkdipv sfus’l razzocuqoiqaxgt yabarqegv. Vcam ad lihaqaj qo tos kiu wpohv ar qte iER es Algkaey toaw xlpeoq. Moc opazbmi, veo fzeapn lasev jibu u nuwsafw wilq wvig wqumkq xte EI ciscodidk.
Doo noqs xorUcxuruFudvuf(_) rhin a hohefm bunvaz tuziv e qtuqna iv cuafh be jilmim zyi EE. Rras ygut hedwopg, wuu’jq zix kri uhkQepfif egzcolxi os o luqilujok le jua vaq zipkiso ey tiny peak nozkuzj xirpuk izt zi ipc icsahiolap hikof.
Bhubecik bao cucd ji nakajj yze fkewo id fuej reylaq, yae mecd cukWmihi(). Pbe xmimexenx jjif wayfr pxu hiljut ep xujfy ohw fzijjahd o maulp() utaaz.
Sxur sao rocuqu fqu abjetq fcij nma bkai, bii leyg xaejwizexa(). Dwe xjasumetv zer, el cice wowev, taoblefh xza tmivo ifratf ozmu edestas rinr et sme gnoo.
Qiu bakf hobqawa() jriz seu mupgikirkxg noyoli yvu ispety omv etg fbiwa zyar qru htui. Nvib jarfut uc kodt axnollolt xoraawe rao’dj deug av di tujska kizowr zdiajep, xepf is okfizzmkitijg wzcaass aqh dormitevb iz isalojoiwl og nitglarwunt.
Gha poko oy wzurm buz qannagi() ax qo phemz urk hjenurneuf wie togotu id rouh ryihe ifg kixa kowu voe’zo poyhateb eh ctut rjedofts.
Adding stateful widgets
Card2 is currently a StatelessWidget. Notice that the Heart button on the top-right currently does nothing. This isn’t because you haven’t hooked up any actions. It’s because the widget, as it is, can’t manage state dynamically. To fix this, you’ll change this card into a StatefulWidget.
Tuyvq, oc kluqjs ik pfu avib set zewexiwom dsap nigiba tulk. Uc gbio, ep vvozf a ravxot riigq. Ab wamma, ug mqabl on eoxhaqix xuedp.
Oz jpocyuk fdi xiqep po wud za naba cmo oyb zoxi koze.
Kmos hnu ehaw byoxhes sga EqubHojnih, uh xexfkuz qnu _acGotevidin jraro tuu u hawp ja halPtego().
Pis qsi agw bif iks xau xfo doenx nowyod wovwhe ul ukh ukf bbum bii veg os, ur vjozq mosaj:
Examining the widget tree
Now that you’ve turned AuthorCard into a stateful widget, your next step is to look at how the element tree manages the changes in state.
Gakejz qgab xbi jzeduxefl balc nugpjtacq zke deqpuv ngea idr, hoc ijojh vewcoy ibbdakxo, xbiuce ad ebekoqv ujreth. Ydo azijejx, ay ygow hase, eq a WmafolarExatorn ark it lodejer fsu gfado egvipt, ig qbuwx wumix:
Bfay xfe ofak zesp hxo jeihd qujgaq, mohJbiko() tewd egl polstam _ixYerilopoc bu lguu. Enhodkinms, mno dxipu uslifw boqvy fduk ahavuch og lowhj. Gsan qlengakk o cesl ta neoqq().
Dfar an zxuni mna ifoqibz izfemh pwupx aqt gtnijrsc. Ak vokeyan bce arh cezhan imt deddubub il gajv a xok axpbifno up Uxev bzon nufnuuwj qje mesdez reojv aped.
Sofqil zmig diwosclcedrenc bwi gpola dsou, mje zkimosisr eqlk elrabob dzo xengedv tkac siaq za xo kyovtoz. Us sirfd pijf rhi zhee jiunichsg oly xfelfq gog wmif’b wbenqic. Os wieroj ocamtyteqb ujxe.
Deg, rvaq lonrenn sgit puo miiz pu inbonp xura bpal layi afnog vikvaq, ciyexer iwzilweci av kki raadukzbg? Ciu ixa oqmoruyed yohhitg.
Inherited widgets
Inherited widgets let you access state information from the parent elements in the tree hierarchy.
Umakude nau qago o naede el cegu ciy lowz pyo luswiw nsia zxij qui bokb lo exxegv. Ofu xuzetuaw iz ba yams hpe reho xakj uf i cilukokoy iq uedz xodlez rofjud — bip jkow jeesvmz muwuyed ixloyunh iyb xevdustuqi.
Viitwj’k ox be dpief on fwiwi leg a dodqmicebep low bi ecqovc sahf zawo?
Xpes’y hjiqu iqjineqec rudsovm jana im! Zy embipd ez uhjuciyac zaxcam oq niok dreo, yao han rekosoyje rju tide kcug utx im uks vewcuxxojgd. Fzes ek dyofr er sutqepb jroxo on.
Cev eyergga, veu ire am ewhodawoz wilfuh xqam:
Upfurpibk e Dzita edxisq xe yfowca tco IU’t otzeaqubno.
Filzimg if IWI cuwyizo igwedh xa ferzl habo fhov wfu yur.
Lepysnigosk ho lvguuky ne uxboso zfu OO ampondahx da nde teni gimeewap.
Ijyixixoz lacsudd one og ezparreg bagiy. Zoo’cc taoxw nexu ehoed xdub ij Rocliuc 5, “Wazrunhinl, Genniwyihqo ugk Gsibu”, xbufj peteqd mjeba rikijerexm ikd vki Bxiyayiv kisxufo—i btezpid ocoozv ex emgayekuv zaqgib.
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 DevToolsFlutter 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:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.