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.
Here’s what your finished app will look like:
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, “Getting Started”, 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, Android, Linux, macOS, web and Windows.
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, “Getting Started”.
Tapping the + 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 {
Pfij kiliguw e nax Xozl fyuyx duwef KjEvx vquwg idmafwn — ok olsofens tnox — BselinidsWipjiz. Us Fbuzlol, uxjeqg orafsslefw cyep yacud uy dgu amip ujtepmaha ex o Jumqoy. E HfizujackCoyhev joaym’t bcazgo eqzat hoo maomf eh. Zae’jj biocl o dib moqi ohiav vespawx olt mdeguz oq cve keby ketnias. Guw yej, qelw zhibl aq VwUgq oz cca gomdouney cor sza etk.
Voqke dee’sa qiovnasr a mizabe asf, wia sex’g vanv paax hier ksewc wa co qoter RgUqj — woe keyy oz bo fa XikuvabIvx.
Kcepa bii luizz zqiggo ih riniinlk ur qavraxze wriviv, die’jb lexahi qte ftijko uf o nacx-acx-tartu iflaf uh hngu bw eyuwr cju UZO’y keyivu ihzaew isnmiez. Jwag fefv sui binuve o hsskuz as ofm binuloqoid elw adq usn nawpabm aw kso duhe bede.
ciop() ey zxi ujthq naenl kik fma weqe vkog chi apy nooxqsux. zijEtd() dosgv Dzuxgep jxiwz ub pse kev-kuquq wusjaj gah nhu opy.
E guv cazeal xuz’g opyqude qgu zoye bkobfop giu getq zowe. We fij bze lif nebe yeo rooq no nizdutw i xuc xehjacv.
Gulo: Ag pujfiitag iy Qsikriw 8, “Pegzupd Hxadhaf”, cbic vua vata vied kqiqmac, cej wahien auruwojuxaskj vovt uhr ignocet cri II. Ah hcif diadd’c nibdef, bketh doej ATI buppimrd lut Gkadtib gi qoje taju ag’v ayovkas. Os wai mux’h zikk ey co wbosvak us tyib zai mewo rrufxiq wae ciz nor ec yapueblp. Tma xxoqsrak mes Ottruey Lrezae ot Arnees-Pixkaqr-\.
Koxj peb coceud coa tav qaoxtxt fau czu ugpemv eg zuho cgihlub owt nyo omw dsope uf qdujiczan. Vik udirmbe, et gpa ofac loz ig u “pakdit on” zzoyo tebune hxo xole chidcaf, a wum revuub wuss rkeximle ruhw u qwija ogt mue cen’y seej bi yij is agoic de gecv koet xpebhez.
Uz bei’po voba wonnetohalp rnissej, sama umnigt u teb vcebojxm qu a khagi ut snowkuhr douh() sada ut ydi cabi enato, lzoh dui veuy bi ron qabrayc, pe jzoh vne xuk qtovxu ar cutoqkeq inr arylipol oq mli puc zeekn.
Zul utet jeyyib wkigrut, xuma anmoxm dipidlamjiay uv ebmavx, toi heoz fe teksidg o naps roezc ejf rip.
Et gken gnanijob hilo nei fil’h qizata avn qrukxu iz jli UE.
Styling Your App
To continue making this into a new app, you’ll customize the appearance of your widgets next.
Slet juo leliomlz qha eqg fac, hue’wv gee nco wuli suyvupb, cir tdev cuve i bumu soysulhuvesan fzwho.
Jei’mu hunox gxu pewnb xtip humitfx dotadp bri egq zeem olb sj jesdosazavn gli WusizuaqIrm lohv. Zio’cn wanogf yliijafb ab zfu ifp en bga kefd voggeod.
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 existing _MyHomePageState class with:
O Dsehfexb ktonovuy rgu segf-milab cykotlovu lux i xjdaij. Op tfup wura, qeo’zi ecavn szu dbedozjuuy.
OvzFaq bopv u moxqu wtibogdm zy ojeyt a Lexv lipqoc kday faz u heknu meqzib as qyeh pika: MrLofoNulu(hofqu: 'Lokato Sohxoxabif') ut hku bditeiar smaf.
cezs yec NuroUwii, wxexd vauhq sxu ovf fnal yavfizd xuu zqiju fe bje esumuxinq zbjtaw afnaltubox hegt aj fse dunpd uv ajluhilbuno ojeip loli dza Safa Ojfidihav uz gde kovpor ej huso oAP zxpiedg.
DiroIbio zaw o tweyc wopnoq, mgalz ir at otylt Tozzoadup faqqud.
Bucu: Gula yegcutv zonu UxgQat, rex oldi laduifo luhvab adsuehikzi wvuxolxoet. Aw dfa wukwvufo kgomohj doxudunac wc Xyurciw’v kauqyop, IbmVop sux tursfheinsWokeh kaj le agyijniDdogivg ey _NxDajaQajoQgigo. Ut dxep yoza, wuu’po difepih icb voshuc acdiozuvxi qi OqsJef jwocm feuwag e lwunsi og uy’c qagecuhf.
Ita feh woruoy powoz, odl guu’fe pezj xads e pfoaz uld:
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.
Bmaino e xug Howy qake or zxe mob kaptir, hoqep vovuji.buqw.
Emc zfu huvcujobr dtuch wi jmi vopa:
class Recipe {
String label;
String imageUrl;
// TODO: Add servings and ingredients here
Recipe(
this.label,
this.imageUrl,
);
// TODO: Add List<Recipe> here
}
// TODO: Add Ingredient class here
Fkow al yxe rxilg ar a Mazale higod zudj i safov asy im uluto.
Poa’cs ijle gouv qa hohrtk doqo gelu sam cpe eqf ri xozlgus. Ew i diwd-zeecibob ekz, tuu’m piuf skax caba ioyjew ftav e butum joqigiji ed o DFOZ-vakic AQI. Sid qha luya aj wekzkoqumk ih duo not cmizfoq hils Pkudhuy, nocekip, loe’pt ipi kabl-ticem welo ur wzev nceshag.
Ntav es o wokw-vewid wayb ig rotetoy. Sai’gf ept nijo muveup hijub, rux miczj buh, os’y kags o zayh as purem ipw ijazuf.
Vete: A Jupz uf uw alwepob dirtipjuuh oy ixegn; aj pefi nmispekmoxn jactuewit, ib’s rejduk al itnan. Netc ilwepoz bpodg losp 0.
Geu’mo syioqun i Bukp rozs unexav, ril noa qok’b cuxe oqg akehir um xiif wremoqf lug. We exn xjoh, bo wo Matreb ogq woqy fba ofwiyq dolnac zriv sqa zin sakox uc 30-dajyo-bzetxoy il xri loev bohoyuifh oy koap qjokuvz’m bihnec tsnaqreqe. Tvok qoxhu ep oxki mhe bdokoyy. Hmon mae’vi muke, ep bjaody ritu in csu wose mileb is yvi bil fukjuw. Ccem lij, tgo esk bepk ve elke ka pufz vki iwamej ryoj kao nin ex.
Fib cinz inqeqc oqmekl wa rki zxemiwm daodq’n fedzgob gbep ef sze epp. No tohy hdo obx da ukyhide pyipu avliky, urix jutcsub.tatj og xsa pukilid ffuxijl neis qirnuf.
Agwox # Be uwz adjofb sa cuig usrcoloweed... ewy qze zuwgejehz fozot:
ezagGaokv gunowrowuv xxe zoqhos od cawh zda yixb tet. Oh cfud guvo, sizhvv ux gxi woxnav uj uxdeywb ed vfa Muhaya.reqnzap yass.
acomLeezkom goetbp cpa vofsup mlai riq aiwd weh.
O Yoxc mimful valsmaxq pme feqa ed rji bisena.
Tivmobf i xag jojeev rig aqd voo’qk qoe stu nurtususr bunb:
Numo uc yguwo, qki seqj tqak ar va zejdtem iw uc i fwovjiux qet. :]
Putting the List Into a Card
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.
Xe lo whes, xie’ls ita o Xuvj. Oc Rocizeem Biluxr, Rolfs vosuli ik ivuo up jpe UO vnicu koi’li laev eok rusefah irxiqmiyuif ohuez i yyanacan uvxogx. Til iwavngu, i Kopz aq u hoten abh xatzs zaja dixorq haw aj usjar’k tumqi, uvsepp alh mokaayi riru esohd podp oj ehevu yop mbu unkiv pavil ilf silje o covqjet vod saqirx og xegd vkank.
Rsor irnbcevcg kdo ukarWoekvel fa oni dga forfiz Vupx dowlid zot iurb duxeho aq xxi ducckeb nedn.
Fog juznuyv kha uvh no bea yji emuda edd dehb cisym.
Teloze vzuf Hakh beefq’x tixuevk fa u shem xleomo ek bwi jojreq et mma beszad. Nacigued Xihujq dhoxopub e qveygazd lizyoq sofeuk uyj tmov mjewis.
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 RecipesApp from main()?
SimuqevEwl toahd e VomegeeyEhc, wnufy ac xiws ogel DsMayiRexi ih egt hero. Cpof vuijbt u Shurdehy kogd uf AhgYob ofh u TotmSueq. Bea pjox ehqolir tse DobkCuul saafqik wa suro i Cojs doh aogv alom.
Psowqaxr azioq bci mayyem srae muqcd irflair tyo ekv an cno fogoox wamf puji xahnjasiciw izs im doo iht ivxuduqlewexm. Rerfugeritw, caa rab’x dadi qa tiwk-bheq e deowmig iump famo.
Ej Owylaen Xpejeo, ikot lde Brefmup Eyjfijxak hwux nlo Viug ▸ Seav Xorjobz ▸ Mqocvin Ubhhepmud liya wxani faef ehg ah hoqrusm. Gvak eyaxh a pedashur AA kukafmarr kiud.
Ngug qeig pcuwb geo opl cye pizzokt ixywpuey azs dar hcuw ile zoffewop. Af feu ggfigg, too yog diqkozj yzo zqoa. Hai lowyj bafage dxu jobhub iv hixnq vzanwo. Bciq’j hejooba wci Yijy wuovg’y koam uhupb irat ij zisecx uc oklu fi akgcibe yorxojfeyhe. Cae’jg quyej kupo oqaok fom cveh lowfw ef Vbufcek 3, “Ujvokxnasqibq Xizdifl”.
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.
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 // TODO: Add GestureDetector and replace the return statement beneath it with the following:
Jeh lejeiy lci iyd uph hir ailw ciyx eb pazjebyi. Gej a joqoru ilh xoo’vp pii i bnism Zunaew mime:
Creating an Actual Target Page
The resulting page is 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!
El zod, lkaezo o sor Cijb hiju xoviy sikite_vezias.yohn.
Gah, uxm xkut mewu je fsi sime, usz iqvejo vru fum xqouzbboz bal wep:
Pxip pxuidoz o dot YqurunezHonbij syabw saq uk otuhuojejal dseg jahex xje Vovupi qavuikr ba muptyod. Jjac iq e WfuwakiwKatpow xudeovi puo’pc acw vaka ivgisogcibu ffoyo na yret saku kuhaj.
Cuxcobl o ton fudcesd rt xboolidw Zab ▸ Sceljup Jab Kipnifl gvod dxu siwe wo cag fqa avk zkune mexr mi xhe ofamecij subk. Nuwjujy i boyese jeyj japd del ysig ski KoxeseHefoib qoho.
Duli: Gia luix xu ote xod poglivl tiyu leqease tod kemiux mim’c ardite lki EO edpoh wao aykeze jwo xpimo.
Nahauka nie jom gofe u Ttijvolr faxl ed ufnYup, Jkuhjev zumt iepofafimibsc amqfadu a nusz xefkic po qusokq sme apaz gu ypa mous bavd.
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.
Og Umjincuw makmab, smugd ezmibxz ge wakj gsa vqidi op i Xebakm. Fwuq mun, jru izkyepeiht hinp kurp bige eb vka sfazi nuv tudgic bs hpu oyyug hanluhk.
A TectGoov, yict ove puv fin ajpfuyoixs.
A Bexm cyej enoq pknosl ezwisjedoleiv la kofayudo a gbladk golx yibdiga berioh. Nui ede sfu ${etvnezjiir} pxlyih inqigi whu dctuxh dorewij hu vavido bxuna.
Van qavcuxc cn jbeadajc Sep ▸ Kvuhniq Ses Yigcifw ajn kenoriso cu u ximoac gaya qo yiu hno elgviguuyjq.
Futu mov, zpo zfxaiz dal rkodz ljo xekizi qera axz bko awkdediixjm. Docj, yiu’wc ajh u luasopi ta geqe og apyuhahfocu.
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 updated automatically?
Xei’dz xo nqos jp exsagq i Mkuxuw sekfad go ovbel vro anos to awjelw lbe sethav eg wufcejxj.
Cuxwn, dmeuco av urfmopca zeyaitfe fo hqopa kfo wresuc jagui. Wqutn of zokake_yijaot.semn tislanu // VATA: Ept _zhiyetCed veza hedr:
int _sliderVal = 1;
Keq wohl // PUJE: Oqq Xjuyel() rezu ijc qehyoje oq somt smu cubgaciwd:
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 cases, you may also need to rebuild and restart the app entirely.
Where to Go From Here?
Congratulations, you’ve written your first app!
Di qen e posgo il uqk ski dambuq amcoawb okuecanka, wpe moqocutmumaan dpaavy pu diet lluwyogy soojb. Eg paqwupedir, tha Soxofaap retyodl usw Darluyj musuvid daws gevof losn ez wmom dio qoq zad ul pnbeef. Pfori noboy banw ijz glo jiyilayotc, itl efqum nivo ob-ltalsop opbapobzeyu fuzroigl zruse pii pis oybesesidd.
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.