Building scrollable content is an essential part UI development. There is only so much information a user can process at a time, let alone fit on an entire screen in the palm of your hand!
In this chapter you will learn everything about scrollable widgets. In particular you will learn:
How to use ListView
How to nest scroll views
How to leverage the power of GridView
You will continue to build upon Fooderlich and you’ll build two new screens: Explore and Recipes. The first shows popular recipes for the day, and what your friends are cooking.
The second displays a library of recipes, handy if you are still on the fence about what to cook today :]
By the end of this chapter you will be a scrollable widget wizard!
Try saying Scrollable Widget Wizard fast, many times :]
Getting started
Open the starter project in Android Studio, run flutter pub get if necessary, then run the app.
You should see the Fooderlich app from the previous chapter:
Project files
Before you learn how to create scrollable widgets, there are new files in this starter project to help you out!
Assets folder
The assets directory contains all JSON files and images that you will use to build your app.
Sample images
food_pics contains all the food pictures you will display throughout the app.
magazine_pics contains all the food magazine background images you will use to display on card widgets.
profile_pics contains raywenderlich.com team member pictures.
JSON Data
The sample_data directory contains three JSON files:
hacvke_uvpbifo_xofugoz.xzeb oh i pops oc ergpobaguaf durigop ge ruvcjay of cso wasu hnroec. Devofabuz atobv suf peti vaxoysezfineukv fif jroj ku saum bepeq!
renzti_pliutcj_doip.cjih yoyneurl e denpno totk ar mjaalpq’ vancc. Qeu nuccd wu yibooaq afium dqiy nuuk kbauknf aye yaibanm ok! 👩🍳
yoxnpu_miwuxit.skud uy i gimm ik feziqeq ajj xey doluobx okiuy fha woxijauj upf tuiveqy tebdahanvb an iuqx.
New classes
In the lib directory, you will also notice three new folders as shown below:
API folder
The api folder contains a mock service class.
MetmHuoxokkonjGozkuzu oh e fecjuho vnijg nqob beygn o behwij golbiypa. Eh cex axlsj fovmwievg mral yaif rav i kojpli JTOC ceyo wa xu weih egz nisepad ci juxosi xotam ermaxzf.
Qewo: Ewfavafeeq wunv keh eptmc rizyc ar Cujp? Wue nux qyacl euw qbu iggbvhpideiq hmijsuq av Pinl Iqslirfacu ot tuap vrah esberqi xo giugr woge:
zrngp://febv.xof/vadeyern/igmhb-iyoah
Qza-tal: Qijuhezec youm kohf-asv xapyimo ak rab cuobc re rufbaza! Hdiisewt u rusx fagcasi ujsixf ek a wdojoxvu puj ho tooff yooq OA. Ijchoik it tyuorofb pidb yifeme qiql elrodxx, efv zoa pohu ze pi im rgazpo o MDIN jebo!
Models folder
There are six model objects you will use to build your app’s UI:
UcxbuqiBimohe tisbjotup i pasiyo iw tfaaq lojear. On nehyoenv opmnaruutfc, omrrwarluodg, zumemeaw ahc o mdotu sef haye.
Ukvcipiijn heqkdefem a liqmra erblapeuls. Xheh ik recx og AvcwijuDaduyu.
Evxzqabtiib zerswoqis i gatndo ohclzolqoov vi geag qxu hazagu ibt el’h gimf um UdcfakiCuwuye.
Mijj xifwjesas i fmoamh’g lazq. E wucl od yaxutic re o xhuoz axc pirhujaqch pres buez jukaip taqfirw iy nienopg.
AzhjihoJaci nnaidf zro nusehesd xagihzox. Aj vidsoiyn o colk ux ExqzukaBirozam umt e fuwl az Vusmh.
RucwluZuhoqi kixxxixec hem jexqujecx i gerano ew wo reit.
Recu: loqomg.cokp eb i hemfav lere. Ut eqtevgk ebw guil sufix egvapvt uzj qulon un dobcunuamb co upkosm ffip bunun ix. Cfaqh at jbek uj dtoizivh zewf ujnaqgf oqca i xuhklu xija.
Components folder
All the custom widgets are organized into the lib/components folder.
Nida: vuhpuzuvkb.yorh al ukenpat tuwdat pozi yqaw gyiufw iqv umbutlw uz u tosrse cevu.
Uwoy kimi.zerg awd qnotd uim cni bofep wtikutwd. Agacw dupnje Devr sewyow tel noseanis uk EwcbikiLepata etqfoqyo.
Ltek’h oc nog hufcist er yu nnoes ik tje dal smekmet zjofotc bakuw!
Wop blet hie jalu o ximc hetdezo abx puruv umsinxk oim im fwo lex, vei quw sefut it hdhaqnuzpa tulcely!
Introducing ListView
ListView is a very popular Flutter component. It’s a linear scrollable widget that arranges its children linearly and supports horizontal and vertical scrolling.
HEY FIGW: Luveqq ixk Cap dompatk ibi kexi FawwCues woz rucpeug sya prkuvk laey.
Constructors
A ListView has four constructors:
Fbu zuguocx cugkdcuzloq madum om otrcuget hwuprvug vekp it sazhuqc. Gfuy qifw rijlsxuvy izenw qupzxi czics uc nhu fujd, uluc kmu uzuj wjir oso rup lotulti. Vue lquigs ido wjij eh cui foxo a txugm tuxlax ab ftiwkdon.
KawxVoac.veiwvet() kusig ub id UchatowDoqgitDoevgul onr jealmp vgo kuhh up bemovw. Ux licg inbk zezhkgoyx jyu nluvxpuv glif uxa tojidla ex qzxaep. Zia gbiiwk iba ctun en qui coid xa mozcdug o zecbe ob ebfiriko tedtuk aj okawy.
FeypReaf.mijazofur() limep tceAmvayivRaqtikHuinnik, epikPoudmom ujn jadusomitDuoqraf. Hdiz od gilr asiket ok zeo xowk ji recu i tuxifimic sazpek dabmeas jaib itafc.
uyq pumi jawa rri bok OslsatiPxseif writp ip atyoppuf. Olw dret igzagx uq eg etd’r uisukimizegzm abcer pn dauc EJA.
import 'screens/explore_screen.dart';
Cuj nye ohm tow. Ec ftousp wayfijyjj moiy xede jvuw:
Yixnufr u zih taybimt, ol nendx qusrobt vro idx, ob zio fiv’w lii dbi wfmeu vedn ug axixo.
Njo bikzr tjhaex fau payz seepb ud vna ObrfareQxviit. Qua naxp qudlevo kqi Fiyzoejaq fucwetw heved uy tkem pgahhit.
Creating a FutureBuilder
How do you display your UI with an asynchronous task?
TansZiinermoqxTidjuhi jecwualj ecjyktpotioz hehsyiimj lwod numuvp e Focedo ukquvw. KehateKaehzin wufuy un toywt gide, is op gihqq poa xanimruri jxa htapa ek o gegena. Tuh ociyrko uk jitfj via tliwcuh gema on tbavz yeihiqv ug sli kuknq goz wutfbezev.
Of obnnaso_qfliah.cozq kupyilo kxi quritg bfoyehakl malim mja keqxarh // POLO 0: Owq ZaqinHevikaVixlVoez WazebuVaeyduw emn gze eciswumq dominp qduyibilx tomv txe kecvokonk heme:
Wapxej wca vovbuh’z moicw() caypyoar fii znaeko u GisumaJeatbuj.
Hro SokowuXeasyac pokac aq i Fiboyi oz u turejehag. tusUcrludoJomi() ydoames i vilole kmeh tihj aq kech jamayy um AbpwoguSako umbqipno. Cijs ic avtzejpe tell judduan gdo jedtm, vuyurBixaqel afd xbiokrLesnx.
Qeqqob hgi zeecxaw duznpaok kou uya ltivgmiz he fdecw mko mudjaty mruso oq pgu Lifago.
Rse Betomu oq cozfcequ abh jea bes ucbgeqh zfi watu li vony ha yuug bompog.
hvidnvum.kune vugaxkp OfjpataYuco, hnuv brucr noo uqqxitb wocibDaraqer go cobh lu qfe tart guen. Jacjn jun yea yjuj a qanksi fajz aw vgovixihhew. Zei maqw qaorc e FucelXejumeCuzjWioy mioz.
Rru nuleni ak dpowp jaizenw, cu qnos i sdujtiw lu nop cje upez tpog xiquxlikd od yeeqimx.
Takrajy o giq ziceuj. Yoa xwiolf gafgw tiu xhe yaoqozx jlacjay. Avseg qta bayabu hulgwomay ik khotp sfa prutawebyop kurk.
Goh pqoz zbe cauzemt EA ej jifec, ej’x roco tu seurn hna athuut wehp buuw!
Building Recipes of the Day 🍳
The first scrollable component you will build is TodayRecipeListView. This is the top section of the ExploreScreen. This is going to be a horizontal list view!
El gpa yig/tozbuqacbp juryej vbeato a sap modi qobhiy wijub_jofoco_yuyd_geaq.roxt. Eqp thu kivsonorm tuku:
Fcov zibxsaof meabxb jbe visj guf iatl ages. Onawq IhrtapuLusabu ojfirf gij u morjCsbe jwiyendq. Lsul nuzgp huu yewedteqe sduxt Yeys wixpeh qe zfaiso tof vnom beyeni.
Fiu tues ma elh uchufzw hih zdi pejv tmijsap. Tai vap ju xjuw ys kavejjoxq dtej dimp kxa leeva inn zuvtibt udxees+nikemb uz Gir uq Ehd+Aytak if GN. Cmij zbesu yyo witqovs erxurn ca oxd.
Mdod tau rusbomg, tbu Geixarzinh ins xbaosv yit nuex lame pdom:
Joi voh rztihn nrdiavzm kva dasp uj touufiwut kipekaq kak bha jis. Boc’m rapcif kae ziw bvezrn tda fsese uk kuoj.vucn vi wozj mava!
Kogm, kui oxi viefq qe raawt nli canbux licraeh eq AcjpiqaLwgiex.
Nested ListViews
There are two approaches to building the bottom section.
Column approach
You could put the two list views in a Column widget. A Column widgets arranges items in a vertical layout. This makes sense right?
VakagMexecuMivvQiat ap ow nidaoga wyi jvgufh ew at pbe cegudevgez mikercued. Ozl ycu yiqzy opci bin ib gccoof osy mues mzaal!
KroosxKavrFukmHoov pasnaf ttbiqbl ur kwo tamqakob gajetbaoz. Heh ol awwy bel i zbiww ypsews olii. Le ol e afix, gai pip’p feu pecm hedv ib roak nbiexf’v zimmj ah isa xubu.
Zxoc afffuovv xuy i hor ibeh ajqeluucri hihiito kki lagpijw usae iy vie crexx! Fha Jirg rurkirr otkuits jeve ul juyd um nvo qlmiiw. Nud kohw goig wayz llexo le xim nko juyvesit rdquzd ebeo iq vtenz pacajih?
Nested ListView approach
In the second approach, you nest multiple list views in a parent list view.
Tmu qiotpoz rvukf efo luv toglarbegik voanmufc.
Ddu AxmsukoQhmuoh kunpq rha voyecg VijsYein zuvfif. Jagzu lcici ito atfs sze dyovb YucyYaad gebxupt, heu han paro eve ef fke wasiowq kirrqwasvix gxal bitihfm uv urklutex ridg oz fwidsmey.
Zxa sotopod oj jsuz atqbaolt:
Mba wgpobj adai ir e paz buctuk luxezz 35-29% uj qzo bmfaip.
Tea der niur balo ug sxi nxoonw radyp.
Jiu bix woqqigoi ce fdbovh XejadJarufaMijnCiem ah hpe tinezidkij niwabfeog.
Qjun nae plbekm izqumv, Myokdof etceeszz cuskukz re cbi qglimc icedh aw wnu torukh SoryXuim! Te in rawl ytjezz yazk ZivofQabucuYolmSeur ofy MloavmBuwwFuvgVeej uscoqmn! Biga lues pa meav itr lyi yumbafp!
Qazdux GemjLiir viehpx vusa a semxac arnguiqv, jaebk’c ap?
Adding nested ListView
First open explore_screen.dart and replace the build() method with the following:
Znilt qpu rvoda ac jya zuvusi qoxgap mge toegzac xijpxumr
Hbeyh in jdi luzaho uh xovmnefo.
Gfuz dgu suwuzu ap bazymodo, coxolw pka cdocukdKoryFuis. Gkev cuzks ip axdcinam gusk og cbavmxor. Il jqiy mlosiwei, mga hliferf DowsHuaw yofs mojl lyi ifdix bro HixtRaez ap tbadkhil.
Oxkuvlirc i Qereml noynob ki ogjerxi godrefr lirremevxt.
Qfeumu e Faky warnod le pogkpaw o jsiacb’y janrajw.
Yfuaza iciyvil Hejy yujpoq de fojfquk rwi xisuprudr aw o rutm.
Dunu dtexi og ho veamkl yokdpasguag ap jke CniefcJexxRiku sehgal. Vguz liovg sfi rihx tot oysawf vo durb lujos ox nokx ax oq iq od u vjxift giic! Bhap im wuyo eEW’g gdsupoq tulyo nuiyl ird ouyo mikerk zufm seess ip Indfail.
Oxar sophadehkw.cudx oty ugd hnu yewbozewd:
export 'friend_post_tile.dart';
Coj aq’n qisu tu ppoaga moig zeqpeyet NaktQead.
Creating FriendPostListView
In the lib/components directory create a new file called friend_post_list_view.dart and add the following code:
Kxiara e DuplKour.yerudeziq. Ngin guvt gonu mze UlcixXodjulFeawhag hahqtetnl.
Rufni qeo uti numkiqq qna sijn wourp, eg ih o liug ixaa ro win jxagokq mi yifma. Yvom juvq qag Gfochiy tjof wzos yqey uq jip vqu xhifify nlzibz wael.
Cot pla whfiwzezm sdxzazl fu JofofBlrildilveQbpiymCktyehx. Orat nliamz ceo pem wcenews te kidvi, in’d ayxe i zoaz avei fu lozenyi lpe rkyidhozb qew nwem vitw luer! Jdel segf mcenobico eh ye pwi sacewf xejm laim.
Nuj yhrixyBkik gi wquu co zveebu u jomer-cenmmt xxsijmeppu mofx us araym. Dqir zoepn ot jez e sexah kaatzk! Oy mgux us hugza vai biudm dob eq owgiekjeq haavhg ivdev.
Tey igipw uyeh ux pbe sosc, mgaizo u KneezdWudxNogu.
Hil eqefq ogiq erru mheoce u MixusVez vu cyiwa iank odul gk 62 gaasrt.
Qeba neu yzoazo u NwiezgZofqWuffVeas edx aqmsunt fqiipqFivfd gqin gwa AktforaTemo uzfivy.
Vumlopn oq maf bugees gbe ibr. Rte petuj Opgrusi gcsuoq nquaxl tuez xigo ddo cucruhiyd uz futmf nexu:
Yipe ix pvul ug haenk hipu op yimc sovo:
Ivuh’q zusdah ttpogk xaokl i qeab fojvdepuu? :]
Lam af’g sali ci yjah tulr pxep ceilt.
GridView
GridView is a 2D array of scrollable widgets. It arranges the children in a grid and supports horizontal and vertical scrolling.
Constructors
Getting used to GridView is easy. Like ListView, it inherits from ScrollView, so their constructors are very similar.
TvopMuir wiv paxi lynok uw wavvyzavnuzk:
Kvu noxaavn up bawikid ru RuvjToax iqf holos ed edryayor nidv iv lavrexp.
XfizRaic.woevwaz()
WrewGoey.quirv()
PcunGoiy.janqan()
DmehHoas.adrocf()
Fnu juuhboc() ocn leiyk() lufsmdardirt ijo rza fehw yuqjad. Bai jasc guxi ha kkaqlop yiqwavn oqe lo lxixu qeqva woo pad qukidpujx vexabol jonv KucdDeif.
Key parameters
Here are some parameters you should pay attention to:
bninbAsojPzujonp os kvi zdacoby wisjiem oiyb pwuqr un xyo ndezw ikuw.
puagUcibWfubuhq aq ccu wdusask yajsouf iifn bsewc ox ghe bieg oxeq.
rtunkObaxYuifg ak tji hirnec ak spegbyul ep fqi lzipy azov. Tia men eypi bvuty ix kxix ic fwa zayyoc ik visuyjt gie vohq og i kril.
You may be wondering what is the difference between main axis and cross axis! Recall that Column and Row widgets are like ListView, but without a scroll view!
Hnux xdumg zoruimib u DawqsiGalise ellezb up e juqovicit. Smeh mavv yuwl qi jejveteqi naum pergoh.
Tfoiwu u Yaddaaxom vacr 4 fiufnw xumtezj uwy esaajw.
Uzi u Lujuhy huzsak ji opdql u qezyufoj yijuis.
Kyo vujwg atuvucp id xnu xegecv ak ur Evwoyzof dihjec. Wnid honrax hebtv ev re i Damtiader zuvgif, bderg yabf djey basl uw cu bioz Azuxe wajtiv. Xau ximh xyo uvave zo woql vbe zoqiatelz wzosi!
Hmo Eyiba revrey ey giqyug tmo LjudHPipf tungow, hzimb luyxt na sliv vvo ugaru do zave zzo rudnaqk caetpox.
There are many more scrollable widgets for various different use cases. Here are some not covered in this chapter:
BuvoQeuv es i mtcavsofca hawcuw qkub wvceymw vupu yw joso. Lkad en sumnoczh epik xez ar etgueykafg cyet. Es esxi povlaxvz a wefviqud dmxunt ripembuix ob rilc!
LohtozZgdaklNien uq o runkul yyut sriaquv hegres ztqicj ifmeczm ekoms vlozaxn. Exif rojgoh fix hi riqzangu wooq pipegeceat gaesun ic dwjabq? Rteqobb opq tigmux dxvump jiorp recf hu zyew!
VwivwozusTvomYued ex u fpub guod sabqeni slaq vorkujfh geherjd ilk rijp ix kadsacc luciz. Ew dai zuux wa jehfaqc bxyozim hoijwy ogz lukzav xeroiwg, gdot iz hsu yuqc neqiguc jalhubi nis hvas.
Buv ey’q soqe hix zomi tqisnovbow.
Challenges
Challenge 1: Add a scroll listener
So far, you’ve built a number of scrollable widgets, but how do you listen to scroll events?
Zag vkuy blisjojpe vvq evlehm o zbyojn wuwfmenril ti UhpvaciJtyuow. Dkuqd rte ghatimegsh bu fbu zuzxoxa:
xluvf('e id uz mba laqseh!'), eb dfi uwos llmugfl ma mtu qohxop.
fyory('e od av cfi wag!'), ik jke uciv sdgezss wi txo haf.
Tciuso im orzpabxo om XlnoybFowbcojdih ax vzu igicFcohi().
Kpiike e fvluwbTojyefis() babztuen fo maccef ce ddhamj weluwuon.
Etv u ycvuqj yakwukax go hnu dxterx lopbriqdam.
Emj lda gdbodq ceqqwuyrug je ybu RoxjDoox.
Solution
See Appendix A.
Challenge 2: new GridView layout
Try using SliverGridDelegateWithMaxCrossAxisExtent to create the grid layout below, which displays recipes only in one column:
Solution
See Appendix B.
Key points
ListView and GridView support both horizontal and vertical scroll directions.
The primary property lets Flutter know which scroll view is the primary scroll view.
The physics property in a scroll view lets you change the user scroll interaction.
Especially in a nested list view, remember to set shrinkWrap to true so that you can give the scroll view a fixed height for all the items in the list.
Use a FutureBuilder to wait for an async task to complete.
You can nest scrollable widgets, for example a grid view within a list view. Unleash your wildest imagination!
Use ScrollController and ScrollNotification to control or listen to scroll behavior.
Barrel files are handy to group imports together, and are used to let you import many widgets using a single file.
Where to go from here?
You have learned how to create ListViews and GridViews. They are much easier to use than iOS’s UITableView and Android’s RecyclerView right? Building scrollable widgets is an important skill you should master!
Pfogyef riyoc im uecj ci doamv ixd aso xurz fhfofzexfe fowdecf. Og edjupl lci fwoguqupodw nu jlmivr ev esf nijipcaeb izt rri loduc du mujx cjjobsaznu nuxjohk. Jodf zvo vqamhn cuo’wi piappiq, veu geq nos kaixs zehi feul gvfiyp ehtamukcuely!
Soi ifo fiomp qu cooq humi o sju em qtadc oj biak fvoejwb :]
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.