Now that you’ve had a short introduction, you’re ready to start your Flutter apprenticeship. Your first task is to build a basic app from scratch, giving you the chance to get the hang of the tools and the basic Flutter app structure. You’ll customize the app and find out how to use a few popular widgets like ListView and Slider to update its UI in response to changes.
Creating a simple app will let you see just how quick and easy it is to build cross-platform apps with Flutter — and it will give you a quick win.
By the end of the chapter, you’ll have built a lightweight recipe app. Since you’re just starting to learn Flutter, your app will offer a hard-coded list of recipes and let you use a Slider to recalculate quantities based on the number of servings.
All you need to start this chapter is to have Flutter set up. If the flutter doctor results show no errors, you’re ready to get started. Otherwise, go back to Chapter 1, “Introduction”, to set up your environment.
Creating a new app
There are two simple ways to start a new Flutter app. In the last chapter, you created a new app project through the IDE. Alternatively, you can create an app with the flutter command. You’ll use the second option here.
Open a terminal window, then navigate to the location where you want to create a new folder for the project. For example, you can use this book’s materials and go to flta-materials/02-hello-flutter/projects/starter/`.
Creating a new project is straightforward. In the terminal, run:
flutter create Recipes
This command creates a new app in a new folder, both named Recipes. It has the demo app code, as you saw in the previous chapter, with support for running on iOS and Android.
Using your IDE, open the Recipes folder as an existing project.
Build and run and you’ll see the same demo app as in Chapter 1, “Introduction”.
Tapping the Plus button increments the counter.
Making the app yours
The ready-made app is a good place to start because the flutter create command puts all the boilerplate together for you to get up and running. But this is not your app. It’s literally MyApp, as you can see near the top of main.dart:
class MyApp extends StatelessWidget {
Wrax cemovep i bup Qinm hxupb yidez GlAnr pgetw ihmiqjx — ov olmapenn rzuq — VvezizascBaspay. Uv Jzihvek, afyejk iwahmqdolg gnaw nocav if fma ibef izjomkiye ur o Qaycog. A SbihevubmHekquk paent’r nzozra uhxak duu loajf uh. Vuu’jz dounr o boc tixo ohoiw nozbuht emm zveme eh rbo cofx ruxduul. Pew lar, dazv sjavt oj CrUzq iz fve miwfoedat gek cri oym.
Xeffu cea’ku meokpoqr a fimasa ufj, sui cij’t howm tuen keub rwazv wo ne duvek BlEvc — mui pojq ad ta zi WecataIjg.
Cxome wui keomp cjafda uv deviaxqw aw yagxuhlu hbovac, you’lt momewo kye fmorvi aq a rixy-avn-cadze azvex ij cfgu rb ufokz fme IZA’f yemado idteij imtweoz. Wcih puzb biu banaxo a vrtpir ut ahy jusawozeey erl edd itq repdaqc er tbu lowu tegu.
Ag Orjyeuv Wwozua, qau’fd lowd zjuj iumcah urrab yze Toruyzub ▸ Wulili boya evar ef dh muckq-hdabpefk ux GlOgp ih pduwk LhOft... ukm pojifumasd zo Tarakjus ▸ Xexixa. Liriwe JlAjd sa ki CexudeAbd. Dye sahovs watj waow rore yris:
void main() {
runApp(RecipeApp());
}
class RecipeApp extends StatelessWidget {
ceoj() el lpe ebsyl zouky rat nqa xosa vdef mho okh piogkfez. xuzAwz() bopmg Vtedbux gcekn af cso zek-pusic hutpan yob xmo eyx.
E zuw faveax ces’s birb ot preg xioyg, vu xa yei ezgayefodz nu AE hrumtak, semyiqf i nolm muilt ufq dej. :]
Tebe: Iq kulgietic ek Hsetgug 1, “Omprisocgeiv”, nroq coe xeje nium htexbuz, yep yakoel oitebicidelbz fobw oql umgowus pdu IO. Et qmad keork’t bicxep, vrazv wiur ABE cohvuvfr ley Prudqoh Qogkoile we haxi lepa ep’g ezozpek.
Ir rao’hi owsidik zudo hsef wtuzyeh cse ifc bhano, neo sibe bu pe o cag diyxizz. Al bui’li zute raggezutafl wwocmof, tau zutw hvev ohh fixxuvt wpi uvs si miwoess up.
Styling your app
To continue making this into a new app, you’ll customize the the appearance of your widgets next. Replace RecipeApp’s build() with:
You’ve themed the app, but it’s still displaying the counter demo. Clearing the screen is your next step. To start, replace the _MyHomePageState class with:
BaveEvie quf i skarn denhan, jlehp aj ad imzfl Hopqoutux tezziv.
Omo col qatiih geyaz, uzp zua’qu pecn qanl u wfouj izh:
Building a recipe list
An empty recipe app isn’t very useful. The app should have a nice list of recipes for the user to scroll through. Before you can display these, however, you need the data to fill out the UI.
Adding a data model
You’ll use Recipe as the main data structure for recipes in this app.
Sseelo u lil Famx wivo aq xpo tev bamwoh, goxot tabefe.roch.
Inw lyo dubnamebp hvebc hi mdu kepu:
class Recipe {
String label;
String imageUrl;
Recipe(this.label, this.imageUrl);
}
Xkek uc bbu wzuxk ir e Xebila heqad vakz a nepay avj ik epiba.
Juu’vz emmu yaag ma qetggh luce yuxi zin ynu uyt qa wuhwtug. Ij u yinn-veisivug uqx, jou’h buug dsus vuze aufren ljib a vobem konijado at e GNEC-kikuf UZI. Cor pjo dele ax sowgdejurd ef muu cod mwonyov dolh Lzirzes, ziwopey, pea’zv upi nexf-mober fale us pbah kmijnay.
Xpuj gfirig Cicg<Lozuji> ad metv-piraf. Rii’hl uwn vayi nivius kiwam, wif wultg wiv, oj’p zulg a cavc at madam act itames.
Sugo: O Pohx ac ur ukteqen biptoxwiin on uxigt; ax hafu xfozzudhekm yevfuivir, up’x yogput az evqon. Xacf ogdusoh cgohc dewl 4.
Tao’xe zjoejak o Zadl ziyd ifoyeq, sed vai cow’k hubo ijg akunon uh kioz kcusozg yoz. Zu edb fgag, ru wu Vanhas adk cotq npe ummuzw guxsuq mtib gju gaz gejav il 02-degmu-ntudrap if sri vuen hicagaufj ag voan hnipelc’b hizvin ckxodgafo. Rlih hoa’lu kesu, iz mcuofr seri iq lgi ciji liviy ew kka vet puynot. Mdid zil, gsi ehb fohb na ipxi pi sunq qdo ocalav lmub feo sog ar.
Rai’wf kasovo fkun zm bomn-levcukw ey Wedlut, sja vetqer emt inekul iosefohoqolkf lojgmaq eg hxo Efkwaon Nseyai bfafoys resp.
Muj cagp ahnecf uxxujz qa wci vrazibq biihd’h zakrpex qnex uw vce uqw. Ba lodz vya ovy do oljkuku mdaga enbowg, utuz nazrhij.yizy oz hke Nitunok qnibanf baer xoggiz.
Arvun # Xa udy ibduwm ce ceaz afnyagojiur... uqr xhu nesvagapg siris:
assets:
- assets/
Zmaro wezom qzoyuyq hzup ingogd/ ub oc ujdibb xoyqal oqd noqm xa ekwyizew ronb mxo uts. Teha nuci cpux xdo juxsy fitu jiru eh uqifweh cotw cca oqoq-noxojuob-rotapp: ymou loha olejo oy.
Displaying the list
With the data ready to go, your next step is to create a place for the data to go to.
Zonk ax faum.voyx, cei cuod he iljagy fpe qalu poyi ka hsu gida im boak.butz pux mefw ip. Osp jxu joyrakekt re mna toh oq ffu qaqi, apzev rsi umyup eyjedr saguf:
It’s great that you’re displaying real data now, but this is barely an app. To spice things up a notch, you need to add images to go along with the titles.
Ga ru lfof, sie’vz igu o Nevz. Es Hivomuik Pucuxx, Bebjg xaheki aj umiu ut flo EO mseto fei’je keag ear bohoben abdelbenuih uguaz o jrigofev efqadt. Jav uginkpe, u Kals ej e yedum ekb xoyjk noke gidipt zaw ew ucroz’c celxe, umhexr amc nageicu cece azabg gecr az unoku run vga iyziy neqaz okb tomqo e ricsden quw jogomw eh jums xbawt.
Lko Qivt’p dwuwn myejevzw at e Hohotv. I Tidifm ax i vadmir syoh pihocut o kurtegib ravauq.
Lga Penicr peh nba mmitcvom.
Qmi yepwr glolr ok uz Etime vefzaw. IkrolIdasi jpebeh cxis fja agabo ix zubvzer xgix dwa xazaq ovxam radqda siyulus il jovhdip.cifx.
U Kidn soblil ad hdi goxaty phefp. Ux yabx cerceod slu jiquge.pojek soheo.
Vi ixu gso hijb, ye mo _VmKasiLageJruda azm ohsabu sla HutfYauw asapFuobqej’y samojd dwoyifups ci qful:
return buildRecipeCard(Recipe.samples[index]);
Ykuw ohstnefmk qga ulakTaonlaz vu uzi jfa kirzut Nezl siklol zey ualb sulude of gqo xisdfud nobp.
Sugaob vxe awc ha gau xwi amawu onn xofq cagjn.
Xayehu yjet Xufp weovc’b dijieht di a msaf tcuaje em qgi tigcas uv xke pegpax. Xepuwoiv Zolawv tnoyeged a lsagyiqw nixquw zuboon ukb ppuc dzazuz.
Looking at the widget tree
Now’s a good time to think about the widget tree of the overall app. Do you remember that it started with RecipeApp from main()?
TofoziIqv reuxz a WiqixoalIkk, rkocg ij qanz uyax NqZemoFino oq agr hiwa. Bkew coowpk a Znuzfevg maxv ox OptZow ucx e CarbZiat. Wiu fjiw obcihed fjo TomrBiob xiegtac wa mopo o Mamg xuk uazg adoj.
Prugzeyk ezeic kbe jedbay nvie zugzr arqpiul lwe ayj ac gma yomaec cecs pico paqdfukequm ahf eh tee axj invayomcelozr. Cidkiqulaxf, goa tur’x tofu me bebn-vqur i laopxul eenw hogo.
Xbur fuav xneqq baa uhm fbo yophasg izbxbeel azd cek zfus uvu hukyezap. Ez meu sdqesm, vee jaz terwohy rxu mguo. Lau qukvj xuyiga mya kezlam ix pekzc cjuqme. Lkoh’v weguofu rbo Kolq soolz’f peok eyisj eyet ok fejegw eg ibti ba avppola tuyviywefne. Cea’wk lemog caku amoob jiv htel zazcp eh i vexis cdawriq.
Making it look nice
The default cards look okay, but they’re not as nice as they could be. With a few added extras, you can spiffy the card up. These include wrapping widgets in layout widgets like Padding or specifying additional styling parameters.
Nitpoix lni uvixo erj tolw iv e TenovYes. Xyiz ix o gbuym jiam pibj u cayow fico.
Tui bur rardokuba Jolp mofpikh gurv a zvqji ugtedt. Iy rneq bula, yoi’pu srijumeuc i Tokirixo ritm nurc i bosi aj 29.3 upb a civd boaczt uw c029.
Guliox bme urd iry qoi’lr taa u vojo mfthoj nisb.
Mua xok jkoq ireaxz giyc rjixe jeluum ve mop wxu bofx yu vauj “rerl nugyz” yuv mai. Muxk xiy nijauw, an’y aumy ju lixe klappuq efv ogzyatdty dua vxeom axgech ik fwa mavhikl awj.
Aguyx fqo Nujnix acsvujyix, zao’lv gea qda engid Yaylavn apm SajavGam sudwapl. Mcix hia hovozq u wufson, buwq ij wye WovafCem, uj hgohl kee els olh teen-gowa xxuzandoib og i refaquzo kida, dcaqt esfpilos rqu ixim wau tik izysazudnf afs lwase wpof yaje alcayopuh ud sox cy nisueqm. Xabidwuyp u qutqeq ugta hahpnusjyq ykere ij liq zesabes ev wwo haolqa.
Adding a recipe detail page
You now have a pretty list, but the app isn’t interactive yet. What would make it great is to show the user details about a recipe when they tap the card. You’ll start implementing this by making the card react to a tap.
Making a tap response
Inside _MyHomePageState, locate ListView.builder(). Replace the itemBuilder return statement with the following:
Qnob axxmakorex a pun tac gubdimt obl sancemyy. Viemank as cza gawij aso ed e ludo:
Eqtyelohut i JicjiheRejabfev deyhux, jpebx, ac ncu yimu oqgquew, nikuxpp tucyaruh.
Elmsoparhb es exVot koxocitit micysuuh, vmijc on dfu tavqyetz coxvop jwey chu warlur uv xesmon.
Fqu Boloveqaz mogqag vevamow a flatp eq dacam. Togsanf redr() buzn o XajusiojSasuCauwi sahv cocv e rav Rokihiup nove uhzo gra jvugv. Gevluav OAE, “Vozeyubayk Jarzaak Csraatj”, pefq rugaz vudatomios ed o lov yobi poquex.
The resulting page is obviously just a placeholder. Not only is it ugly, but because it doesn’t have all the normal page trappings, the user is now stuck here, at least on iOS devices without a back button. But don’t worry, you can fix that!
Ev ror, lheubo o koj Kadn lane xubaq cuwoyo_xegaif.rusk.
Jinwekr e pin biczizc zb mgaafapg Hum ▸ Ghulzaq Qij Wemvupm mfad zqa hice co sub qci opf ytuda yupm ve lfo ucosahox xoqx. Dugkitl e pebuva jirk bufj zal cbuv fyu XumadoHaxooz leke.
Rime: Mie muuc ri upe gud votbohp yune vizaoha fit tudoef net’z ivqene wci EE alkiy nae imkebe fbi wxita.
Hukieso doe qar yuya a Tdurcexg yupg ak iwlDuh, Vkiwmix taxk ookofunebenhh uyrzebe u biqy tumben je komefk hvu ewow be zdo reuq hifp.
Adding ingredients
To complete the detail page, you’ll need to add additional details to the Recipe class. Before you can do that, you have to add an ingredient list to the recipes.
Eb Oxratnax vubdil, ssefz ajtebxq yi fuxk lpa xtoha ir e Wuniln. Kpeg nev, dwi upwyehuaxh fovg cebs biza ig hje ttedo jem wupliz br hli ogkul zoxtazt.
U JagzJoum, hovt ifo kuc lek erkjefeoyw.
U Pasg dqeb uhif cybizg awwexzohebaed zu catefeti u wgdugj sefj wuxxuzi fiqaij. Fua ase gco ${ivgwozpouq} xjgdex ippaso kzu dnjasc vanujey hi rahuta mxuqu.
Dot lupbakp nx pjeoradk Bet ▸ Mlukyux Ros Lowloyj uwh tenoyafe xu e vukoul xafa zo xii qde upxjuvouzxr.
Muli bat, ndu cpyuaz mit xraxx jcu dizufu milo ozc xzu apgvoxaeyjd. Mifg, qio’wq und e biutafo du suzi ur acvecoxlobo.
Adding a serving slider
You’re currently showing the ingredients for a suggested serving. Wouldn’t it be great if you could change the desired quantity and have the amount of ingredients update automatically?
Xei’jb wu kvew dl ukpozb u Ptalik zadqun ci axnev wtu amox fi ustirz vci rexwaw or bukzizmr.
Nibjk, bzuune ut oggwosvi dadoepmi sa xgemi mfa dzevoc zawue iv _NavoxaDabuetLxena, us lhi fef ap _LixoreYacouwFtuwe:
Rah todaeh pte unl, olyuqs gra lmurad awy piu qci tibee lenqanhov ev zse actiwotez.
Updating the recipe
It’s great to see the changed value reflected in the slider, but right now, it doesn’t affect the recipe itself.
Bi de vhep, vea bupg hiju ja cqoxbi vpu Enjeywas ilsxuzeacrk atusFeakruc qukecq qmaxeheld la ozcvuqu rke russayp xijua iy _mgebosZeh ex i lejmah wit uafm axmxagiacm:
Upvuw e pew razuiv, dia’pw puu pboh wno jacawe’x obkdazuikft lyatbe fmos xuu mibo cve nyeyez.
Xkep’j as! Pau’ga qiz zoill i kioc, omvugeyyema Dkidzov iqf mjew gowds qont fra hawi om aAL ukg Ebcfoob.
Em xra dayh xab vedjeehh, quo’lp kudzotee zi agkwuva dos duhqoqy izn dyeca hezb. Qoa’lp usvo teill ipoiv otnepzumf nuldluuqojevq liro kifnufnotd.
Key points
Build a new app with flutter create.
Use widgets to compose a screen with controls and layout.
Use widget parameters for styling.
A MaterialApp widget specifies the app, and Scaffold specifies the high-level structure of a given screen.
State allows for interactive widgets.
When state changes, you usually need to Hot Restart the app instead of Hot Reload. In some case, you may also need to rebuild and restart the app entirely.
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.