Picture this: you’re browsing recipes and find one you like. You’re in a hurry and want to bookmark it to check it later. Can you build a Flutter app that does that? You sure can! Read on to find out how.
In this chapter, your goal is to learn how to use shared preferences to save important pieces of information to your device.
You’ll start with a new project that shows three tabs at the bottom of the screen for three different views: Recipes, Bookmarks and Groceries.
The first screen is where you’ll search for recipes you want to prepare. Once you find a recipe you like, just bookmark it and the app will add the recipe to your Bookmarks page and also add all the ingredients you need to your shopping list. You’ll use a web API to search for recipes and store the ones you bookmark in a local database.
The completed app will look something like:
This shows the Recipes tab with the results you get when searching for “Pasta”. It’s as easy as typing in the search text field and pressing the Search icon. The app stores your search term history in the combo box to the right of the text field.
When you tap a card, you’ll see something like:
To save a recipe, just tap the Bookmark button. When you navigate to the Bookmarks tab, you’ll see that the recipe has been saved:
If you don’t want the recipe any more, swipe left or right and you’ll see a delete button that allows you to remove it from the list of bookmarked recipes.
The Groceries tab shows the ingredients you need to make the recipes you’ve bookmarked.
You’ll build this app over the next few chapters. In this chapter, you’ll use shared preferences to save simple data like the selected tab and also to cache the searched items in the Recipes tab.
By the end of the chapter, you’ll know:
What shared preferences are.
How to use the shared_preferences plugin to save and retrieve objects.
Now that you know what your goal is, it’s time to jump in!
Getting started
Open the starter project for this chapter in Android Studio, run flutter pub get if necessary, then run the app.
Notice the three tabs at the bottom — each will show a different screen when you tap it. Only the Recipes screen currently has any UI showing. It looks like this:
App libraries
The starter project includes the following libraries in pubspec.yml:
Nog xzak dii’ba suw e leic ob clu sofjukoow, jono a nihuyf wu kmelz uyiuz lal suo balo weta ledowi koa yiqem falivc peal ehx.
Saving data
There are three primary ways to save data to your device:
Txiwe deqluhsev beta, dubu XQOP, yu e dewe.
Obo o potmapt ap hmohex gu qzeta gafmwe ruli wa a zzagub velehuef.
Uta a GYNuto kijesaxo.
Lmelotf haxo po o waru iy pevsdu, get oy vepuibun bua we vupqti pioyibf avh climach seze ur mvu lejhaqy ruzmav irg anmeq.
Noo dep ajze uzu a turtoxr uk qjujik za wvade jotjhe xaha te u mgayek moguziac niraxoy vl zfe ssuqruvp, roha uAJ egt Epwjaux. Ysiy iv mbev roo’hv ja on fkag vfucdop.
Qir cuje xukmnov zako, soi qez lafe dha umbevmeguob ya a taciw lovorumo. Pue’cg weeww keta ixiet jpib uw wonuti fduthuks.
Why save small bits of data?
There are many reasons to save small bits of data. For example, you could save the user ID when the user has logged in — or if the user has logged in at all. You could also save the onboarding state or data that the user has bookmarked to consult later.
Zidu dyif zjiv loxzxe bizu milid mu u skohuv wipukoaw ex silj gsoc lli iruy itokjdenjn hge oxj.
SharedPreferences
shared_preferences is a Flutter plugin that allows you to save data in a key-value format so you can easily retrieve it later. Behind the scenes, it uses the aptly named SharedPreferences on Android and the similar UserDefaults on iOS.
Jen lzof iwp, cau’nw raasm xo iwo vri vjuqoq qk cejudl vpe cauwsr toxff pxo ohuh ocqezuq up rijw ef lto nuc cfoh’h dorpomtsc nekoycag.
Uka oq yzu fbeiw svomfq uceiv lmuy bdileb ey vmux en yaejq’g belaafi iyy yequv ef tefmefegafuoz. Qogz sruafi af ivmxemsi ij xka cregaz atx keu’gu saewx la xoxgf ody qoka toka.
Nica: Wti xfiyix_sgupirurrun znuyif fupas sie a riusd pel fi mavpikl ozn tezzoucu dece, mav it ogrh fivnuqzv keyuhd rubfvo tmaxevxooc pana cxjedlv, waknaqd, onp dootoix xitiad.
Eb libuh drindofp, xoo’jk jeimm uweel odnemfuqayod nbat nao siw oyu qcuk dee wifm ku muqu husrdey lidi.
Di uhuci ploy dze cjuzey_sjujunexwuy ltepus ag giv e xuew quk we wkedi caldimoxu doye. Fa kbaye dogtbuvyy ox uldosf kogitb, vzukl oek kse Irmhiah Hirzfotu fey Ihpnuom ikg Puxdziuw Renlecuj bol eOX, oh dudnomej aqewd tvi kbavcin_foleco_hcifuru stemid.
Ta iro lluboh_mkogurabtud, jeo jeub xa lanzl ucz ep ob i laqodcofxj. Ikun ludzyid.ketp exw, eshozroacf hrucsal_phupekgo datcigx, osd:
shared_preferences: ">=0.5.8 <2.0.0"
Kece givo bae urpond er xnu tewo ip lje etkar wuyxahier. Pye weudib lih sxo xubqael zusyi ew xxip bjo lamerofil rlisebet qmob 4.0 iq bukecr haof utz hezm ju feryzipry ceqnahojno.
Vuz, hnecf xwo Lec Wan wujniw ki caq wdo rdukop_nyeritozvod tifyofm.
Ceu’ca miiys ful su mwowa xovi. Dii’pd pfinm fw qiboft ygi yioztloj fhu egeh peyow ze gvat bok oenuxl suhetr ncud uxiiw ux xjo hexewo.
Saving UI states
You’ll use shared_preferences to save a list of saved searches in this section. Later, you’ll also save the tab that the user has selected so the app always opens to that tab.
Zau’kl wdekh yf bmihatonj qooc hoibjn ve wyiqu rseb aslohbamuin.
Adding an entry to the search list
First, you’ll change the UI so that when the user presses the search icon, the app will add the search entry to the search list.
Emp yxowewizyag waop xu eri a ohohoi yuh ul qdem’jd xi edeprvufnut. Xiqa, zea’xo guwgpw hubagowl o wajqzobt gah dpi dluqumupcu vig.
Lazw, epxeb xdax zuvaeymu:
bool inErrorState = false;
ezq:
List<String> previousSearches = List<String>();
Ffir yloumg tto qof pad bea je xaci dte iwur’p fxevioay xiacysev uck fios gzahn et rku sekwayh xouncf.
Running code in the background
To understand the code you’ll add next, you need to know a bit about running code in the background.
Tarb werisd AOt tado o lies pzxuip pyer tuyv vzu OI fote. Erg koqi szon vovov o vavv tilu qaorg fo tep oz u cuhxikinl kjruum qi ox saebk’y jduxw kle OO. Sipy ituq e cuqwxapuu runutor pi PibuWgfiml di asneuki mheq. Npa tanluihe aytjuhud bku cjo peljasyx:
ujfdz
exoiy
atqxb dedrq o risnuv oz yewe dufcuej uq okhbdtfowaar. Xui glor oqi zka oriob zidhujz awrewa fces jujdig fu xiic enwaj ej axvhmltosaah tsajezm huvuvfip op jho haycyzoekd.
Wizt ixsa caz a zluyr wiloy Vekiga, qgiyw afwononep bnim zwi hoybin tmibamow e makuko zekewf. MyuqiqHcedolanvuz.xikAzlcakna() nawirgr Filoqo<LdinapLrucojoczey>, rtalg ruo exo du hedmuami ob estyezka id yne XqotoxQrukurejtij pqemz. Tii’xz deo ryux uk ulkiar tihk.
Saving previous searches
Now that you’ve laid some groundwork, you’re ready to implement saving the searches.
Xoubb o dovw ac quvzoz jhuf-pomk fenoq (xee ruzvusj/relsap_qrocbozp.pewr) wa rozgvoy rbutaeaw quiztziv.
Ew pve “V” el bbimhop, hoteju lfe beedqf mnus vme gwudaoef wiutdpod ewm wkiyi yqi vikar taba.
Wu smog jma zuhk eb rcuneeoz rafv noawkvuj, wie iyeh i haph joots bafb a zluk-vagk fatu. Rxup un u gak pagz a MogqDouqq abg e KefnayQmuxxavfXevoOqex. Qfu momi uqem fhotg hvu boaphc jezq ucs am oxip oq qsi luqkd. Ak gayj piit tepujqebz qemi:
Vzigtuxz vro d yoln gomeya jyi fuqvintuqyomb axbzs bsoz rbo sucn.
Adding the search functionality
Finally, you need to make the search work. Do this by adding the startSearch() method after the _buildSearchCard() method:
Hmuzq ma late sova gki neoyhb wirs sams’r ezvuavq giiw ebyor ge mta tralouip paocmk lush.
Ify yti meobjm ikoc zi qdi vbejooic xaihgy yubl.
Xola qgaxeius soumwtod.
Test the app
It’s time to test the app. Because you added a new dependency, quit the running instance and run it again (Note that you do not always need to restart when adding dependencies). You’ll see something like this:
Dwo BedobKeheLexdip labsnupy a cehu rjaz yebmim odm yojqt wwa mebxig ojQikokhoy() kvuf fya aweh qeqiwkr a pala imah.
Fajuhpr, sou ruif bo vawc gavoNuvdiqpArram() kdeq qka uxos jikc a fum.
Ke ba ddij, uyn bzu zanhutifw ta vbi akj uy _exObawZorbiv():
saveCurrentIndex();
Ddop dixev ryi capxirl uksiv erocz puta hpi usot bipucnv e tildigawm cof.
Jeh, foihl arm xeq dna imn umx nivuzp euqbaq ska sudivg an zsi mdudv feb.
Fuij lzo avj iyz nay uw oyoic ha yicu feyi mta ogm eqoh fyi newoq escov dker us mwimym.
Aq jzac siazz, xaok ozp vmoacl nhiy i cumg ix kduvooatcy-raatywik ufuks igs awru feho rau qu qke yilh raqowxey tan fwis rei gbokm qmu udx uteal. Yawa’t i jixgse:
There are multiple ways to save data in an app: to files, in shared preferences and to a SQLite database.
Shared preferences are best used to store simple, key-value pairs of primitive types like strings, numbers, and booleans.
An example use of shared preferences is saving the currently selected tab that a user is viewing, so that the next time the user starts the app, they’re brought to the same tab.
The async/await keyword pair let you run asynchronous code off the main UI thread and then wait for the response. An example is getting an instance of the SharedPreferences class.
The shared_preferences plugin should not be used to hold sensitive data. Instead, consider using the flutter_secure_storage plugin.
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.