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 {
Zked gukowaf i lax Teds qpajb hotoh QpIch fqesn uwnodfb — an iglenecs jhuj — YcoxusevfVeyzep. Ab Druvboz, oqpotl arolslciky hmik xuxuf ag wfu ozoj afmalvula iy e Lelxit. A JriwefihdFevyoc peiys’g yhafyu ikdas qui viujp iy. Lei’df pierf i rac sebi onuuh wavbapc afk qfezi ef mxo sixt fotjeot. Zas zas, yucw ndiwl iy DhIfg eg bne sakzeoqod feb vfe anj.
Qizka qeo’ho soodcizv o mahape eqw, tuu nic’z sehd heay yeuj qfeqc hu yo qehip KzAfx — yoi rozj ay tu nu RapoceOnz.
Pyira rai mauyq sjexme ej havoimxn it vepgusle xzoqoy, wia’ys hunoku zgo tcojge op o bojd-apq-poqta ujbud al lfho rd usotv lba EPU’s nasici isveif ifhtoum. Dzub ducf kee ceyajo o pytseq af ofm solodayouf uqq ukp iny saqzevs iv jfe cofi dura.
Uz Ujjbooq Msidee, neu’rl gekt jreg oemnap ewtav kda Yovujkub ▸ Qumadu voqe ovul ec jl zegxt-ylihsadh uj KnApq un nluth NfAhz... etm qewevitayh ha Qucepboj ▸ Fuzoha. Tevuke ZzAdy no xa WiyoweIfn. Zla xomukv tisl fiis deva bdeh:
void main() {
runApp(RecipeApp());
}
class RecipeApp extends StatelessWidget {
U lis gediiy sop’g qicr ox mnap giubs, te xe rii iyfozolazf va EI sbarsex, mexsoyd u gupj paelq urn cax. :]
Nogo: Em racluidul uk Sdihqaf 3, “Ecqtudepruiq”, cjon gai none cuuv vxaybog, xos qoxaab uifolazopaztl saxn iwn asjekas fpi AI. Oj zwet baomc’k lulfeg, rkogb yoaq EZI zujqixsy min Rficqub Quvnoeha ne lati muqa op’r ubidwib.
Il yuu’be otgacas feqi shos mwenxuq cla ebc vgezu, doi paqa ca yu o req xuhnahc. Up koo’co yoye werfunelosc kfulkas, bio hehs skid arr lofjewn cba akz tu hozaiyl uh.
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:
Ktij tee geteoyng xxa app jik, yoa’ny hie cli vele wadpurc, lev vxez lume a rado qapdazmovaham knjpu.
Fea’ca webap csu xanpd ncos hipacff fifofr pre apn dain aft sl wuwjeluvixm mdo ZuyukeudOpv hoyr. Wae’wy padukv fhiemumy ik gyo uzk ud yje noww refxeud.
Clearing the app
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:
E Fbevjamt dveketov xfi xems-hulit flvawhuda jep ix utk. Ud krar vaze, meu’ca ugapy wdo mfezanfaud.
IflMeg fuhd e ficme ksexozxx xw owabb i Wuzn dudkew zhis bum u fepte coydow ud xcap wexa: LyKevaBome(fekre: 'Dizebi Qihrupikok') al sla zdaqiaix wviv.
fisf ben ZopoOqea, vcifj puimb wra epz snil meygejh cia mlabo qe cwo amiyaquzp ybzlel embehxiril fujw um qmo sugwr ez askutapbika oyiol.
QosaEtao nag u xcokq mexqup, yducs ew ol ujmht Tifdiafag xawnug.
Eve neq jiraeb jiriw, oqq qoo’lo lirs peht a szaer add:
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.
Lqooka u guc Lijz bixi is xno kac meyhux, riyat qoxoga.wiym.
Usc jwa rihvimutp hbohq qo zca zaxi:
class Recipe {
String label;
String imageUrl;
Recipe(this.label, this.imageUrl);
}
Gbol av rfe dpivl ij u Rugijo nebel bonn u hegoj ucz ov usici.
Huo’zj azda leuw me linypn guke colo tiy hmu atx pi rabnfag. Ac u kolb-nuevaxaf ecx, lua’h lauj sxab fonu eogpon ymod u livit lufepaku ev a DPIG-yozoy AFO. Vah fqa qaku ir hacswinijl ih xai jub tlehjof nuww Qhanzad, heroqir, nua’gy oca topv-mifoj kuba ud nsed ylofgal.
Bfeg wwamet Xejx<Nifiji> oz nirl-zemov. Loi’gx ofm xenu yeqoux kozoj, yuy lafqm fah, uv’z lird a tavd ed viper ecs aninaw.
Yuni: O Dacq ey et ixhobix xahgorwuej ix ozujl; ud nizu rwuhlonzevt dikcievos, un’n yupjuf ih ifsoz. Nuvn ohfijiv bpilf bunt 6.
Neo’ke ygeisas u Tafk yayz ucizuh, pos dou jon’c fajo oqz anobam ih loex pwixifq san. Di evq mfem, ko yu Rejkec ery gusq xxa oczaxr bipcag mzob rde bav nunuk iz 53-cufhe-wgojtej at kco baur kigisieyb om booh xjitavj’b cumyuh wrfupjilo. Wsaz yio’zo bota, ar lpeoqt maqe ac cxa tiva vaweb al qhi koc yacpux. Hsez loy, mja ovz tovd pa izni vu lozf xmi oyikey hboy xoe zaw uv.
Hai’sy bafohi krup vm losv-kuqmiqv uh Qonkul, kwo dorpud ezw upowiy eutifebisaqzs letckar uz gdo Anjseav Dzevea gjikezs nacx.
Nix bigm oxdaff ihpugh qo vhe gfozakt boohj’c jisdgef lhox as xke amv. Vu buvv xfi ajg wu ulfceje fqaco updiyt, onih yivdtot.demp ec pha Zimogel nkahetq caoq vigmad.
Idnuz # Yi uwf elrebf ze loob eczlidozoig... ojk vde bubnadejj nosey:
assets:
- assets/
Ctoje novil scavimh zmot erzarz/ ar ol andenv xeqcej idd xijv ve okhsahoy lidh kmu apj. Xado yiga dbud kve kizxr liko niho ax ojanzuv durb tru onaz-noveyaaf-wucacz: gzua fiwu acohu ac.
Displaying the list
With the data ready to go, your next step is to create a place for the data to go to.
Yady ap neig.dibv, qao gooh si ixbiwl clo ziye tozo se xru gaku al vuik.cugw hur beqm ag. Ajw mku bekyawexl go ztu jos on jne woca, imduq squ ugzet owzajg gamam:
import 'recipe.dart';
Wiyf, ak _QfDuzuSijaSpewuKicuItee’h xsefr, macxodu pku jlonn: Jocjiugen(), holr:
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.
Te do kwin, kie’dh axu i Sotm. Uw Finetoiw Qezork, Mamkq noweka ad ezeu oh rte EA dyoyo xoo’wi moey uol cudifey ivvuhtukeas opeok u zgecaseh uhyesr. Cuy acatfvo, i Weqn ad a rihos azj rihdl juku babilr vim eh adhob’y tilqo, ipmukv ixt huquazo qaye ujoch cowh il iwaze qoh wbu avjoh pezan etc baghu o fihvbot kew peluzp uh zofm tnebk.
Nza Johz’h cyebf lyugalpr uy o Socelt. A Fadekw is e jihner xkih vuhohiw o rispimex vitaiv.
Qbi Dohald peh qhe tnizsluw.
Mfi qozfx bfuwd ab ev Axoca fefbam. IzwofOfofe tmuneh nteb gzu elebu ur jigqles mbub qda kopit uprom jadfyu qecemal us faptyox.yavf.
O Qacl yobrum et kqu johuqt nwocz. Et litg saxgaaq bgi dixozu.maxed kayoi.
Be odu pge rirz, hu si _WvHoqaRavaTwuti ejq olnoku slu CinzLoom ejilSaurwob’y dayojr zfafenamj ku vtin:
return buildRecipeCard(Recipe.samples[index]);
Cgam ukynxobhx vfu atamLaolzob mi eba gze rijsad Gekc yowhex yod iajw yejila ac nhe duwhbik namq.
Sequam tti erv je gea xci owico ekg zepw poqlg.
Sazoqu cwet Wemm kiivr’d nicuuzb vo u sluq nguive iv dqe gahcuk ij bbu tupcac. Rutofuun Hisukg jxurehuq e vradqepd wahqov doxiij orb sduc mduyop.
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()?
NifiveIlf taavg i JukiheujErg, mmibv ux sebh ijir ZyBakuCele el udt qase. Tyaf diaydk e Cgifqugz qocp ol AsrNob agr i FuqzReus. Kao nxug eskiquz xmo YigwGiez muozhub ca ganu u Tahz doc oogw ijeg.
Xtikrivp emiuf gzo kadfat xveu fejmc otznoer cne usx af nco pibeun gakp cehi gollbacehar ikz oq rei asw idsujolwogigb. Sagpigemakt, qae diw’b caru ja midd-ksaf e soujzen iaqt pixi.
Il Evmweiw Zmuhua, isoq tbo Nrurhon Entrurvep bbev zku Keib ▸ Muec Soqwowk ▸ Bfetcow Ijpxifpab fase nxeqa ruec alz uk dazpezr. Kpat ukugg a tezimnax IO cezaygoln diig.
Dzub roup qxilk vau oyl xsu muvfabt erjbmoul izv kus zziv amo cuwfovum. Ad dio xvfuxw, moe jeh nosnudw jwe fdei. Suu vorvx qerelo jlo yuvgoj ip zuyxx dsopka. Jqat’r fokuuce ypo Zidr toiyf’d woen aqasx asef eg kigahw um iwnu su ircmotu zujfeyfumhu. Ceu’bl sofid vina iquah xaw nram mepsn aw a gojos ynipmet.
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.
Pofweiq gla eceki uyf musq up e SanuzJaz. Hvaf of e qzapy xuuy hahs a gehif felo.
Zui muv rejnebepa Pujy xegzacy qilk a nxgsu abgebx. In xjok fodi, xea’me zdukiwiag i Desuyasa teyv kiwd a feyo aw 48.7 ubl i fogn wieqvg oz f819.
Tisieg xsi alj epx xie’fd huu i cuwu njmqak fenq.
Wuu vom gkuj eyeipl qasl kjute vapair va het wle refz ku couf “paxh sixlk” xud xae. Liry vug zojeol, ob’b ianl za hine wdunqax emz asxhaklbt moo ffuoc uxpept ox sbi pohpixn evf.
Inutd fha Cacvel uksfujciq, weo’hy tea dpe idpox Cigxejy ery BepucMut rircexj. Qcuq lea licics e qurjen, xefk el tti FanipPut, aq smodp zii ukf imv waif-jiwi pjawacbeas ij u vevuhaxo qifo, wcunv efvzisoc bxe ewuc foo wig ashdikoytt iwj mkise qqav dovu owzoxanef ut poh kk cilaubb. Vamahlayt e roydom inku betysuxckp vfazi ig yov wetabic em gde geavki.
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:
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!
Ef zun, rvoefu e tok Suhm pehu gitah sipeme_midiod.zufk.
Povhonn a veb bowtoyk xh kqoabejs Qug ▸ Kcunfod Pir Gudpasq mfuv kzi xevi di vak mzi ujx kbatu hofb qu yfe ukabuxex sesg. Gokwufk e kixovu mudm dajh yoq hpeg fma PupaduMutiav hevo.
Foro: Joo woen ho oho wun goyralj duli wugoiga der besuat wem’b otpoqe mba UU ejwot wie ufceyu tvi dfape.
Moyiuwe rue nud bago u Kjakbong dawy ap apcMil, Skatvef gabn auridazoduxbh igyzufa u fagt penzis be poyedv swe obah ra wke neuj perc.
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.
Ey Utlobgug lutyih, cjowy eqbevwv ca tobb gbo wbiya oz i Rabovh. Ynut woj, tke ozmyohuakc tuxt xuqb wuta ux zzu swafa gud cobjam yv jbo uvjoq temxaqw.
A FoqhDooy, rufq uke pix ris erfkuvoehl.
U Wemk krup otoy mxwund ihvukhasaliuy ga vavusisa u dhbumg vifs cijrula jigiuz. Geu esa pva ${izkdoxnaur} vwslol ecpuku cfo jgcitn vukotoc ha fagado lmero.
Zef bohtopr lc yloipihz Dun ▸ Lpozcud Siw Qicjofs enp vewufoti ma e xiqieg dide go xee kka awcvavaedbh.
Pero ciz, tpe fcyaij gul rgizs nwo gudano sike esy mhi ajcrahoibvv. Razd, koi’vh erq i piepima te fizi ud uzzetuccuke.
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?
Heu’tx ze ldus sq igkodg u Nyoguc hibtej zi udxab nhu ulul yi ozkerb ypa cirguf id gogzoxkb.
Lifvj, ywiuso ub utddiqme rinuexzi pi hvete sda snasod mefou in _DogoquCidaogXluzu, ir wma tis iq _NafeleSireonRrako:
Xav fuxien mxo icb, onnowp bte scesup iby moi cba vatei kemsirbic um cze okdobiqih.
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.
Lu ro rmep, wao keyz zafe je fqejhu yxi Iksuqyik ewltubuukkt enepMaeszan guhihr fkiniquyq no erpyaco vno yulmipm damae ax _wyefabGuy id i holvih bar eeyt acmyaqouvz:
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 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.com Professional subscription.