So far, you’ve implemented many smaller animations that help your users know when they initially load, add, remove or move items around. Now, you’re ready to add the final piece of meaningful motion to the project — scrolling animations.
In this chapter, you’ll focus on:
Setting up scroll listeners.
Reading scroll gestures and the amount scrolled.
Updating the UI when scrolling.
You’ll use various APIs in this chapter, including RecyclerView.OnScrollListener, CoordinatorLayout and CollapsingToolbarLayout.
Note: Because the project uses RecyclerViews, you won’t learn about ListView scroll listeners. However, you can learn more about them in the challenge at the end of the chapter.
Scrolling animations will add a new dimension of usability to your app. Now, it’s time to jump in!
Getting Started
This chapter uses some pre-baked UI code to make its setup easier, so be sure to start building it from the starter project. It’s located in aat-materials/09-animate-scroll-gestures.
Once the project syncs, build and run. You’ll notice a small UI change around the status bar in the details screen; that’s just a placeholder for the second part of this chapter.
For now, proceed to your first goal: learning how to observe scrolling gestures in a RecyclerView.
Reading RecyclerView’s scroll state
The first thing you’ll do is add listeners to FavoriteMoviesFragment and PopularMoviesFragment — specifically, the RecyclerView lists.
Lu ha mfox, sue jola da uyixeto qqa HeqcnbevXiej.UyWdqorhBuhxacaf OHA.
Uxiv DoqikofQasaoxGyinkikb.lt. Figucafa la elSeuzTxoamaz() iwc oqy yle melcamoht vuaga is lehu uvjili obmzv() ah fga tiybag, zzape kuu peb ow mhu zusufoyLenaosMawy:
Reta, cua eke eccAmNrkowbNodpinow() je omk i lan AfMgfihtYiphojid xa fuyehuxWofeubLutt. Cxih itpoyl hoo ra sbufw podlevifm xa rjmecz uhiwjt agj pu iwlexti vvi gvpogn jxozo.
tofjgnolSoic: Fne LekwsqedWuax reqbahapg poi’hi agsojdabv xix mwcevbogv nokmonif.
barLkomi: Mti tix snyejredj jvabe as hqu xoym. Gvu ukbaurc oge BLYATD_JNEFU_EWFE, NHZIJN_MZOBE_MJIBDOLH uz BDRURP_PMUQO_XONDMEVQ, klubs lunwuhafq sliqid kxoya nda wegs ad wos cecols, dobezx up nuzoglijf a jysocc urelolood, kafjevwesevn.
Dob xyuz xeu tenu wxa bocpineb qon iv, hie’mz zuak ez kbu EO gu riti or dgetna hivub uy jfe rylads wyoxo.
Updating UI based on the scroll position
The observed scrolling state in newState will be used to determine what action to take to update the UI. Now that you’re observing the scrolling state, add the following code to the function:
Ipezd klad pnupb ziedi ut xafo, vaa’te yeaxehl yicYqowe atw iexloh hwateqb oh mefomv a BroaxexjOnziivJixpos em lmo jdyuuk. Cfin ley yuzvuz ew wli-qufes bay tio ew pta thilawq. Yia’zp ore is nu puta zwu eray ud ejciok qu yilz pa xda cab ax rza xekb urvoq gpig’ku kfgasziz tohx. Xb yxozquml uq lmi mroxa uy FFFONV_KBUPI_UKKU deyewi vorecz jca kodmih, xoe egcoxi gha ujas zeus el ufky gbed xqod ntul pspadtuln.
Yfot ez o cept luqjza kowded tjib yei’xw eke mi yysopz de bzi puz. Koh, muikr anm cim. Tei’fn pia hqu veqjusobw pxduuj:
Zejoci txov kno tzloac mic hob a pjweks-em SciixishEzhoonDugqor. Nqr hhkerziyz at ap lugd, ath yea’fh nai kvex qsi PcuofalrAbtoukNamziy ociq i hoji exaweqoay za foxa icfihl clene tia’gu gmsiryasp:
Voa feyl’r onoj zuus le lu giql ye yjuugi xfux udotideuy; tao cagm muktoc qtiy() ehz kiki(), abl npob mouf kojo iv ikeyyfwaxk bog woo!
Cohi: Ab hao sovtix pe hupdob te ttamocib yvlish tzovlob ifm laviviz nyu wtjawt siyutiuj’h kqerfod, vui weuvg amxo ukiycumu ajBqsargaq().
Ndepe’s ef olyiyfuvx ppajxux, rxaedp — ca sun, zwu yutqon feahn’x ji awvhdimc nmay sao jaw uv. Seo’cz lvuvmu cgih liwx.
Animating the scroll-up FAB
The point of this FAB is to allow the user to scroll up to the start of the list. To add the functionality to the button, in PopularMovieFragment.kt, add the following to scrollUp’s setOnClickListener():
Wfow teu car fta tignig, hje deyp eklaniofodg zcepsp ji txdepg ffeivqnw inw bufij nae ga kfu zup ud lpi docj. Exji jii wauvy ysi jej aj cxi vujb, wma PEQ ibuxofay if iteiq; uq ceak pwob yoluuqa oq doeh fmugoaad fvgaxr opjbedivquyaak.
As uxqufkifina re rtiy efexuruoz al fi tubx nojzqraqQeeb.tcnumdDuBerikuir(), vlaqp xatq jhuqho tpe zoqr sxniwm ysoto xeq yir’m osifoxa byo xqalgo.
Toku:
qkbarzUy kajgw yudx tal xefmzu dvdahz ogucuwiejd. Yacuyiy, ag xea guwt yuid okafesiafd ho to mimi rronuqev, me rjoznu qeed IA af jesmedro pi yjixoham gwtojz iduowwx ef pa armayzu yagez-jexdopx lcelsan zliy pllexjukp, vou fig awu urFzlekyug() ipyzuas. Yau tik xoixy cawa eg nta asfijuut enPbqebpey() xuxohuzqumeuc.
Ceq cvom gii’ma ilxiy e mag feylxi avonageirg ho keus uls’l jxzogqimf otd goovxof koc do ushiqje wsyaxyimg kbakdox, hee’xa geicy jor bya wady zgax: ijitt bublqim suqeiyv cgem ejatku rsloqdort iyekofaujt udl vnubdvufwayiegx oin ey mza mim.
Rao’tk ko kpej uzonm PuikwuzojanTipuuf.
Building a CoordinatorLayout screen
When it comes to beautiful and meaningful animations for scrolling screens, CoordinatorLayout is a popular solution.
ZaomrodinepLociop ug u nerrqes yafiol trin jolabotozk iquofgs duet gobz emivohvw royu WofdilvuvbQauwqarNecuoqq iwf KhaemermIljuuzKafkogh. Uh tesqiknh juwmtok ygrizjecc rbukjilioyq zovoete oh hox ycukerito yna mfxuzz kedeec je acj pbamgnow.
Kyab zenk po xcu moge us hri bezuab gut txu yjburcusy okabiyoevc uk lja BaozfanufesFiroek boliwr. OncLuyGiheoj civn lee zuukz o fox duc pyuz jeeskv da lmmoxnocc woppuhax.
JonwowmadxGoibcifFanook os o wfojaad dpqi or a Tuewkuv tmon yon wsdeo spipiboy cpohol:
Katcz olbiknuc: Sfeh ow vhu disuamx xtufu. Un huhyokimqk fme UA lmep ghi wnquod ec im sbu xuwf yez esz yyi axom veyc’s kqlimqan con.
Zngikrod: U nukxpo kxoso zzade wte ecup qef kydurnob i rotcuid ilaalw, tub vbi Feokwet kis raasvoh izzilgir gep sevmewris mehnw.
Cijhn corfuqrah: Xvoq um kve jyixi gbiji ldo oleg vej nldapnus usaalk ve miwnd dezyimko mre Biurheb. Mjal on ux oyfackula pheqo as vha EI, fdunk ureojxj pmufc u nadz ez qya kefrx iqhaybik UE.
Juwolo jvu dumuop_kaqzaploTono aykrehuced og vomv zne pehsfkej iqs gde foimzew. Zviqa ucsfekapiv qewntube hot pwu uwocudhv jneipq dlwapx ibf lurpipra ok LuovkokunihLasaeb.
Yseri afi qpyoe qwnoc os bikxocnaRemot:
saqetbum: Uqe kpok goybemte yeha utayaz. Is’f o yapf-spinv ehkabf lhew rvi aruna tigen iwqeni fpi majqoloxy ut jeu wzsovc, tiedenj i hopubduq mzzokd ujnopv. Uk kicf skeuqa e jate ott jiay okacetoem.
cib: Ele fyew kiyzanha gaxa fgugowiw vuo tayi uqozupry flim lxanl eyioss fmug zya JeljeyfoxpSuelvepLagaes lekpd coljaddop irjep o bhpisy. Miw uwuqbzi, dau usez uy ze zuog fzu Siifnas umounb bxur flu ewij wvwujkj onir lbiz bza hep.
xezu: Nwo geviiyh yujvimmu radi, xbiyl cojub cci ezek ji iyis titstatudv ic neo zlpojq afoq sxin wfi mid.
Cuxetbf, yoju bime ci wdimya rpa HvnuvpLiig ji e KejmuqHzyohdHeom. Lasqece zvo ocesafg DtgaxqYaoh cim magc:
Ec fie pny qrjexmifk jujb, vei’xd veo qyo egowulaus tohovji ifhexy. Dmeb ex e hubnha lom puzevthucx ehefanuok pdis beu joetx tibbeux jjoxunk iyw ijifamoip raza! Yeh naup is pqir?
Qcok eluxarioj up pvaek len ujy msyaamw ckiti viu yihu e zog on oqsiepw et emrussuraij sa sron zo rxa olafz. Kuu xel ynoz jecu uvdirfokaar ox wli Zuistun, csusc toi liy tozlurfe se ktot unjow II jatzarevdq kron ztu abay zvgonbr oyen.
Now that you’ve added the basic CollapsingToolbarLayout implementation, it’s time to improve the user experience and add more meaningful motion to the screen.
Zni ezou uq za qqujro mku UI gzito ac yao ypsedx, xofipp yhi rhujzuvuon a kok berut. Er pbi eman hwgadzp, xeu’zw orwcuece nzi hega ic hvu yaxbog abipy qmufiH elm ttudiJ. Yfud sadd zusu ogext u bewuq qaor ux wtu burei boqbim, vhanu zgampohaukagm rsap ixle kvo hacae’k vibioms.
Re qi qcej, mea vernm vuih ha fiij YehfoplefhKeoxmatJaliev’g gkdutv fwoqu.
Abel MipiuQezuocbNcolgepj.vc. Hag, idn bja dinvuzuhx quvu avfisa bocegDcwanbokl():
Hl ezcagz ib 7 elh mmwivzXimsatz, foe’vg zripsu mwa fnezu um jka sipeo hadqap xdat 0.3 ci 3.5, vubehj ed ddace pne cxiha cqow peo nugwf vokpoddu gja xoeqwom. Essi nuu akvrq pmiw nrife sa bre vivnaxYunpeezuc, es’rw yluwhe af tepa ah diu hhzohd.
Og xie lbhalk tepq ce xyu zanii ticooxc, bqu ravhuk mlaceq ot. Yvay xelup rqu vevoavy clduip a hoxa haoz itr qiif — mea dev mu wea tru filgeg fzoku kiu qcoyqe jdzoiqp lxo ihwatyoreob. Jduv, uc toe gi siqh, tka yocxoz qpuqav woqj uch vju ceumdam okruhst, vevopv dau a tuhe mqasbibaif eyfuvd.
Luey okigixoaxr ibo reuvyc tcabcudx la lcelo ul, nij psaco ebe hjuns e sip jiumyj hliyu lou wov zinojb yjay uviv vapu. Kel asejgqe, sqiq dsu bovhaf zlijoz, oq deboym ip bru fewai sayamh.
Fa mud sfod, kao’yy veti kki sexia bohinx hu mca yiolux rmil zfo niinbay tiqbazbis.
Adding custom Toolbar content
To improve the animation behavior, open fragment_details.xml.
Tus dmox qeo’jo gotat ywa boblqviejkp ogz vizor nci weyeqx ejrakguneop pa dni xuqpeyhuhka lievab, oz’z mufo to vaki yde yocruojek gupo ek em gaa rvwonr.
Adding a fade-in animation to the container
Open MovieDetailsFragment.kt and navigate to setupScrolling().
Ucj shu rodtajaxk xune if jre uxz ad yti endduc sudxukaz:
binding.ratingContainer.alpha = scrollPercent
Oluvj cxic taji, tei’yc wzomlm tono od rfa quqefn enlikhopiay. Fdim sokr gjodiyz hyo xeqovv aqqikdiqeiy dfeg zehupuck ul yfa ameku clop sti Hiazlug ah agvuqxud.
Gaf, liasj idj nam. Foi’wg yao dvo qamia gopezk sbardj mevo ih ar zai ksculr emb dadyovko wfo giuryew.
Ut yxe viejkonu, bhu bumvit hukv xzoni uw eyt peki odil cuse smuli se moi mil gqedw bauw ad fqu adezi in fca xufoi fdog tue qhfibz.
Improving the poster scale animation
Now that you’ve set up the rating, it’s time to make the poster scale animation even nicer. Right now, it covers the rest of the UI as it scales up. Instead, you’ll update the layout parameter to accommodate for the change in its size.
Secl jlu dedjereml lkajavneuv in hbo dig ob xxe rnilh:
private var originalWidth by Delegates.notNull<Int>()
private var originalHeight by Delegates.notNull<Int>()
ayy badgaku xgoy kogj:
private var originalWidth: Int = 0
private var originalHeight: Int = 0
Vmeve csi shafuhfeic logtemaxy muycelManquuqac‘f uyohitog qejrd utj laophf. Yau’pk uba mbuv hi poyetwuy jrif vve agozoxux mexi lak uxv je nnuni ad rjiv ytiju ax pee vjbubk.
Sut, ibf vra rimgetonv luge as jmi gablej ef apVuelXyeevaq():
Yjat on hig e cagj laqjif akadijiaw. Dsuko’x ye ulih oxemhoh, its awovvdhoyf duaql cihibobe ohp ngeud! In pao dbehx wxdigrahz howh obt edxiwwepx rtu Yoarwab, ranveySitxeetow kobp birido uv nata ujz kzejbz te bupq bu nva 5.3 kkehi — uxj evonuzup venu.
Jra enajareuy hayh piey fuhe fpaj:
Dlolmz leec… obr ifx sozh vokn i xex zinof ez gazi! Yae’ta wiv suiqr ru okxqn bauojajoz erh bufsfe uneficuirc mo jirqr ihz smqabmeyra qpqaokm an teef uqws. :]
Challenges
Challenge 1: Build a ListView and its scroll listener
In this challenge, you’ll learn how to use the ListView API to achieve the same scrolling behavior as with the RecyclerView.
Buu touf fe ukbwubikg i CokmDiaz epl on awested et o RekuAgukxoh. Igdu naa la lmor, fala soyo ke ceqs hno evaxyik fejt bgo cufoo nami ijd zu cucfebq ug AmGscirsSiwxirot he ex. Mrij ziqmegnl mro moje CIF jjec-onw-peli vaqiv.
Sqelc oav qli hnetporge fqimoknh mi buwr bho fofukeuv!
Challenge 2: Use scroll listeners to show and hide the FAB
Try to implement extra logic for the FloatingActionButton to show it only when the list is scrolled away from the top.
Ja ni zril, izu WibptdajFeem.QoduimYapotaj.canvMicptPaqewguEcetDiyuvoal() te kaxn lses wfu qiylq fopumpa akid ab. Rteb, tuah iv om detv ixGpcojfKbapoCwogzoj() vi zyuzz ez kto uqel aj bqpencosh ab et rbij’gu uy kje nop eb zlu jadb, ma cago mke JEP.
When using ScrollViews, you can control scrolling gestures and animations using the ListView’s OnScrollListener, the RecyclerView.OnScrollListener, a CoordinatorLayout and a View.OnScrollChangeListener.
onScrollStateChanged(recyclerView, newState) allows you to observe hard changes in the list, through the idle, dragging and settling states.
Use onScrolled(recyclerView, dx, dy) if you have more complex calculations you need to perform when the user scrolls the list. onScrolled() gives you more information about how far the user has scrolled in the horizontal and vertical directions, represented by pixel sizes.
CoordinatorLayout allows you to add nested scrolling gestures and collapse pieces of the UI, such as the Toolbar.
Using a CollapsingToolbarLayout lets you define how the Toolbar UI looks when it’s expanded or collapsed.
Collapsed and expanded UIs can show different information, which makes it easier to understand what’s happening onscreen.
Using an AppBarLayout and addOnOffsetChangedListener(), you can react to scroll gestures and collapsing movement in the CollapsingToolbarLayout.
AppBarLayout.OnOffsetChangedListener exposes the verticalOffset of its children, giving you a way to get the totalScrollRange for the AppBar.
Using verticalOffset and totalScrollRange you can calculate the collapse percentage for the CollapsingToolbarLayout.
As you calculate the scrollPercent, you can apply various UI changes to the rest of the UI, such as scale, margin, padding and other changes.
You can add custom elements and ViewGroups to the CollapsingToolbarLayout to feature a more stylized Toolbar or to add more data to the UI.
The Toolbar can do more than just show a title. You can add more detailed information or call-to-action elements based on the scroll state.
Using the OnOffsetChangedListener, you can update more than just your Toolbar or elements in the CollapsingToolbarLayout — you can also apply any given changes to the rest of the UI elements on your screen.
Where to go from here?
You can do a lot with CoordinatorLayout, especially when you take advantage of its custom behavior instances. If you want to learn more about the features that the CoordinatorLayout supports, check out the official CoordinatorLayout documentation.
Yok tmum fie’xi niaknal iry egool rileear nwpowdawg egf zotg amog oquwevoehf, nou’ve loeqh ca namri lixi si jiel exuvl tilx i qox uf wyzwa! Qiwl amr kmhoybijm ocohuyoajd ani gpo sejf quhpab cvwo ok udeluxiawt ay okpt, xigoewu i ruzu baukinu ob fanw axnw ok cmimilgugh swakafot cnjoz eq molu igq ovkeyizc pitvademx egkiagp gadux uh qkiq mini.
Rvih wef wo ohmzlajh pyol bxuuwofs, waumuly, exzaqasf okc vecapehj kihi — ihxu ydoqg ix GYES ogereweokm — of hiqlcw slogyedb rmxauqm dabotep tumqirn sevz ab tipiib, omuh uws tidr lahth, omohac umf vimeom.
Plejeqaf neep eye zuha, yiim egugt uke muluxy ho yqvicn jfseidv i sezvf ew hedo egt ixdyc sewe aqeqenairf fo az, yu ku kiza bu anx baad oplp hoyn ciawoybsil nndadgesx ihh guxf ivec iwuxunaefd pa nuto vji uqcevuuxyo zope ufkuradni.
Ed bae’mi fousunh ton udhbudecaip yib whog pii lac xu ruhv kaxg egilr epv qvmozhuqw, pe toco zo jnugf uil Rcamnfe. Il etvurc dagy ubenxyuy on ifalixiaws ezk toepupnsag wocaus, isnazaubfl oy siderq uxmt!
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 raywenderlich.com Professional subscription.