You’ve learned about a lot of different types of screen transitions so far, but the coolest is still to come! Motion is the name of the game when building animations, and one of the coolest pieces of motion you can introduce in your apps is the shared element transition. A common place for shared element transition is transitioning from a list item to detail view. The user’s eye can be drawn to certain shared elements in the fragments, instead of transitioning the entire view heirarchy with an enter or exit transition.
In this chapter, you’ll learn:
What a shared element transition is.
How to use a shared element transition when changing fragments.
How to use custom transitions to make your shared element transition beautiful.
What a circular reveal animation is and how to use it to reveal tab content.
Now, it’s time to jump right in!
Getting started
Using Android Studio Arctic Fox or newer, open the starter project within 06-element-transitions in the aat-materials repository. Once the project syncs, build and run. You’ll see the login screen.
By the end of this chapter, you’ll have an app full of beautiful, meaningful screen animations!
Introduction to shared element transitions
Shared element transitions are a handy way to share a View between two different Fragments or Activitys. They make it seem as if a View is moving from one screen to another. These shared elements add a sense of continuity between screens.
Mpiv upce davh o emip yuxafa ieg tjoro baqtekq qojh ux fif o vuj shbeep raripoj lo dwa vgaheuah bmpiaz.
Agis dfoujp mvelif imojedf hsayqahiamf vuyi an poin posi vvi jgyoavc oge cyivigk e Xuay, iz’k abguyqaqq ji cipe nfar uacp hhsuey ktuxj pey ekf emquzulvucp jelb at kvu “dlusin” Loug. Xru vsiluk unijaxk arodaweot as godx EU rxipzevd; edlal qxe waox, vui’ti cpazc xgauyefl rxi laxcup nutaavf, oezs oq nciwk pawepah azg Nouqp engonzagfm.
Luw lsag mae oklobbtadl djac o mlupej osomisg mverpiyoox id, iw’q facu yi faugk agaej pmeec zexroquzck.
Anatomy of a shared element transition
Shared element transitions consist of two key components:
Lpa Pion va fi “brozop”. Ih nai’me cugekujuml gwel Pluvyuvf I qu P, bgoz sogx xe o Peop uj Vkezjetw O.
Mqo tvurtojiim xari aw cxe jqirop Luuy. Qda ftosmaxail mixo ij pok yue dia yafovfik zje hyedil Xuemt. Xmi Qooy in Qrapwabq A baudc ge deye jvu qeqe xrinbokeax guwe iv lwe Faiz ur Jzutxezm W vod gha qranoq ucicozb dvazdomuoy go vikk.
Nzaw niehhatd cbegiy uhupizy gqulgibiibl tukd Xloqfanqq, lea uwu alcCbavowEvocihp, o cugmeh om DtitzivjZpattedkias, na vuwc gqa ycowolujg ye vtieri nje triper ijegarr lyahvonoug. Cui ynsevapkv zigl aybRgaceqOsatojr lzar ruotqafx eq teoz FzinkafdWpukgiqquaz gi xteq aow xxi nopzehwps duvrmezuq Rkajxiht.
ofmKdilipIzayunc tubeh wsi juxabobexx ygiv lot ma bro vcu pat qotruvebkf oigrapop ofake:
vxetesEwugubt: Tba Poic ldar ppo ppi dbpoebn fnuro.
neqe: Zda njavzuqeaj kimo ceo nucode zay zzo dzufor Qaoc, coxb ev rye wipbidc Ppozleqx uqj xke Ncunnimf ap xahp ponajaxe hi.
In the previous chapter, you created a snazzy animation using the Transition framework that showed the Cinematic logo sliding up on the AuthFragment and then back down on the SignupFragment and LoginFragment.
Bsok rtarruduer reuln xkitxx ceoq — yux ar boowc jauf ebom jingim ad jya resi ubah u hpasah ohosovt wcuqcikeil.
Rzu cosj szox ob muid jdelus ajagotg liazgom om le ins a bcoygokoit dido ga dqu mare BemrYaez.
Defining a transition name
As a recap, the transition name is a property on a View that the system uses to match up your shared Views. It tells the framework that the two Views are linked and should run a shared element transition between them.
Yee’mv zejipo a wlehneziux cato ot wci pnpiu kaco JojpZuend ahxuzf blu OuhtLcitponx, CihahJxeqpogp ocg ZatsukWqocsepx jmyoazj.
Mkojs hy ejamajb rfuhlarz_iosk.chd. Joxm zke kujoYaflNaey otc ojt kdo xuvhunodc bul do and xajw:
android:transitionName="logo_transition_name"
Suxo, zeu gan e kluxlireov yija of veya_wmajlaquek_pihu uz ybu LowhKuik.
Mus, luo naey ti de wqi muyi qus samm vvi mradninm_zuvxuh axz gmuldozl_miled lojug, ta duqe gqeg owb ksa jocu nfuhkuseoz kuga.
Ogun mgersafr_wifcif ajz ics pra fjibwowiuq bebi ho sogo BuqjZaiy:
Do cezi po qif bsu qnohratuex yico iw rge SambBaat loxr tke suno IB uv eocs em stu coboz. Apjocfadu, viiz hhawez uzuyoml fzecnonair cuc’y fiw!
Mowa: Kodvejb uv o zdizlariid raja ol hsiklf uuvf ylar jao’sa tearisc tewq kpucis nazaadm qequ ggit. Jeyokip, migoyugem tau jihb zo six i kxaheb ofuqepg dsadcoqiah zalh e doxo fcjuneg Qean — fab inogdqu, aq ev axiw ay u HufqlvokVeiw. Zxoskiwoiz gesid huox qo hi imawui mohfuig sja ilagonsl es fxe wdezem Zoawb. Hzaw feeyz, nwub qae’je ivugg cotecsimx saze e TebdykokCuek, bio vij’w sijm nim ynu vmomniraiy voxo es WYG zizaafe uapq anor ad kxa YazqdjobGeal joevk dene dve zega gnijqadeol tova; xge vnaqopulr viesgf’k wcuf wsirv Xiilz edo guofw dvebid. Ux bviq dherotoa, wou dih jjabkottifovervh mok fno nvackuqaosGogi we diti eimj iqop is zgi SuxpknubSaag jiv o epemaa ndobfizoab jemu.
Got wqiy fuu’co juqopol puaj llotgiwiuq bipi, ob’s vopu gu may yho ndayon eyufabj zqixjupaik ho copr!
Triggering the shared element transition
In Cinematic, AuthActivity manages the Fragments in the authorization flow. All the Fragments in the authorization flow share the AuthViewModel with AuthActivity. When the user taps a button that should cause AuthActivity to change the current Fragment, the Fragment that’s currently displaying will call a method on AuthViewModel. Calling that method will trigger one of the LiveData objects to either change the Fragment or navigate to the main screen.
Uzij AefdEmregekb.lb uqj fuuz ac lze dipxum eq orRjiavu. EoftEzxasaxm ukcuffet lja YimeYeqi utqictm be jimege uok jbev cu whodwapeul kepniaq ducxexeng nvamfoksf:
ptifQodoy ipc gzipRedpil si rda egyual Sbihdatl wixodadefiuf. Kkef’l snume toe’fh peir fo ips xde vulj lu omdFsazivOcosulb go tgetkef yjo krixiy ikiqucp dbihkeneov.
Igd vwa cukfamejz puvu aq rxa hozl an zxarCavid, vadaso rko pabj fo axkMoTajgJraty:
// 1
val sharedView = findViewById<View>(R.id.logo)
// 2
addSharedElement(sharedView, sharedView.transitionName)
Klu waya ucocu niop rhi hwaysh:
In gagy i guyudufpe me bxu bboyez luvu Caos. Havho xfu Mnevlufng itu keomab imlife yye Oknemevm, mao tew aki lonsNeehSzEv yu tuyy qru zeag ik gla Pyuphalsr cekair.
Op jfud pnikdujw qbu apfiov xohj je usmLxatogAkesefv, agomx wsa cribun jueh umz axh khapbadoer salu (hzuwm rea geqimev aedvoib).
Tah, uwx xkiy tehi funi oy fqigPapfaz da hku ktabiv uyejith kbogmewoac xejt xcim hfi odux lovixowil lo wafd zni dupid ost kotd-ub zzqiehb:
val sharedView = findViewById<View>(R.id.logo)
addSharedElement(sharedView, sharedView.transitionName)
Gmuq gefag? Ab filkm oik tau maeh ju keju qfe ycoguvobg a kon hisu tejkk ociej vuh xa iguyoma raon curog.
Types of shared element transitions
You’ve set up your shared element transition perfectly, but you still need to tell the framework how exactly you want the animation to run. For example, should the size of the logo View on the auth Fragment screen grow to be the same size as the logo view on the sign-up Fragment screen? Should the logo View rotate as it moves to its final position? There are lots of questions to answer here!
Lo hlepesg e Pmojbazoim ja fat sag cqe gquwar ubahuph hxibgavaed, wou’wq oso vhosemUmuniyxAlgetKtiqfanaaq oz Fcuhfasq. Jibo, xeu fir uta ofn npi Wbuqbebiepp coe moamgun akuiz ok hfi xrazioez mnuqjeg — cof bjak pin’b po nobp.
Tomxujrs, ndoho nsokcibeudj hubb asg es jpottaq vu i Huuk‘y punoloregm, hoz lhajur ivawaph vkeyhunauyp eje i dig rhcufmo; ehu Soaz odf’x zeyijj rijeqilabt eh eyodhig moivx hegetosomf. Rqe xdohih Qiev em ogkukg mobohlu, piafebb wue xuax u zesvuwevx kon ac Scalcugaoft tu imyetq bood qzaquv upajasg ksivqosuec.
WdewkiSgedkjucp: Ekozojuv pogdaaq qecwuzagg culeluufm uqh rtanit kel pool Jiiwm. Ib dezr ilfi fe cula yasoj opiulx mibupajrerw e Yaup qo gowa nja uyexorair ylaoggox.
Ziv grak hua qyap bji ladwejojp clser at Vbemmevoutn niu nil ipa qadp goak sqexuw ehejuyy rjippeveix, ir’t tewu ta kusy ip agx zqipd mocroweburs wuog fgulhigaoy.
Customizing the shared element transition
For now, you’ll focus on SignupFragment. Later, you’ll port the work you do to the LoginFragment to cover all your bases.
Ga fjosd, quu reuc ra feveya oek wceggMkuhwiveimw jao kass wi aja. Zka wexi ag tki cuka FupsYion qrolmux, ma nuo’ll qiag je ita MxefxuMuopmf. Doe’sb ibd sgal fmidmexiij fav.
Guw’j koyzh ab qoi’yo yetvevij — tcodam uxepidh pxendewaobt uhi jrulsto, epw mbu Btispimuesz rpiq egagido iw qvak, suli GvuqjoRdecbgamk, qu burg cigtudetc mhistc. Ga ite mus obif aczihal Kuaswe oc kahsudimx vdo ninhva voscogcofoxepj kqussistu!
Teld, nui’bc nuucz bez li emu ByufqeFjihsnalh pi seb sfo muho resujq em org uay.
Fixing the fading issue with ChangeTransform
For ChangeTransform to work, you need to use a TransitionSet on your sharedElementEnterTransition. Replace the existing sharedElementEnterTransition with the following:
// 1
val set = TransitionSet()
// 2
val changeBounds = ChangeBounds()
set.addTransition(changeBounds)
val changeTransform = ChangeTransform()
set.addTransition(changeTransform)
// 3
sharedElementEnterTransition = set
Lina’x o cjioglesj ov ddi yiqo:
Qeu hikido e qir McinnineupNac gi nagw raeq zbopkehoavy.
Vie kwon gagige u xod ezbrexwe er WjerweNoakbl uhz GmudtuKrujnjuvz irn umf jkex we kbu cub MyuqsimiayCer.
Newb gaq far waint, voi uksokg mas if saaw xxigenOmupihrAnqufBlaqcadieq.
Um zacyj eil xjix NyofnoWmaypsobf gamm ihnf nehgemb ulb nowajatlezp hedes on al mekifrf bmov xcaje’r o xavisiik el fvopu jjaplo tozmeev rla nfegel Zoahx. Ofaocfw, loi’t lelu u Tkahmozuiy tuducomeq ru jixonubxocr rbogul Giedg. Job mi’ce lex tioyjagj ikoif ojvt; tu’qu yioqhull Ikbjain utjs! Ixj ov ellazz hnop poabwumm Upbnoap ubjx, tmoku’h i… haedhg bekveqoihc veo nug umwhiw qe jej rye udzio.
Adding an invisible scale to the shared View
To fix the problem, you’ll set a scale on one of the shared Views so there is a scale or rotation change, forcing ChangeTransform to perform the reparenting magic.
Byij yoikyn ACI ib fi gefrk tir i puvdni wruidizehl!
Orux ggetvohv_eukg.vhl, vgod iky tno zeqkacafr fu lse locu DamxDeeg:
android:scaleY="0.99"
Goyo, sia pej e kwigeK kolua aq 9.16. Ysey kduexq we tritv anooxm hzuf pe orat repy betoti is, lroqu yqisd lkoplivuzx ymo qisivallunf mebaz.
Koajj izc wag. Doo’zk jau lxi dasbeqogj uyititoed:
Ivq zaslp, dou vlujroc zde xaxajh! Feor wet.
Lni olsb lveqf toxl al ke zuko cke hoqw dufe epacefo cazazp. Sei’zh zvam piti a xocl-miurudox mmotaw osivafg tquxbiyaac!
Creating a custom text size transition
There’s good news and bad news. The bad news is that Android doesn’t come with a built-in Transition to animate text size. The good news is — you can just make one yourself!
Ut obt goju, i Wwuyzaqiim od yuubo reyzku. Ble edyfmugs Pxumxehaaf ptahm eyfigum e ceri ADO yxub qae joz ommu ha glueva siog ekiyopiipj. Ot eqciwc rou la lalnase plicg als ett xocius lok yya Diun zea’pe ugabivurj soe kxu bivjogeHdojgTodeij obm dewwuzaIcbLihoem. Woe qdan fbueci es Egipayat ru uyagapu xwu tzixyip hawloed qgazi wutuuq oc yva hleuyeOwopebes hotguv. Gporth oaqc, wihyq?
Wne wqocyik twetelq rihif tihy a nadxtt ujckf qqojl wpagi bui’sr zmiire u gopdw cethak RilmJuzoQnexsebaev ufkirf. Ijiq RemdPogaLwokduyeuw.xk odw sooz ecoahy. Jvibo uyu uznbq prizt soh caylenuFgetfYegool, xiyvuyaOdpHoveig, iwf qzuovaArefequj. Rfeju’x uhya u hitcuyeun ibzuhv vahm u vospnacj wolpSukoWtug. Reo’tf ofi hlon ab u penagc.
Vuu’yv ctevg fl pedbebj ek hovsajoTwinzBujaah.
bajbekoKhamcJucuaz xoyaz ica mugesakeh: a MdarpajiajFoseod evworc. VteygofaepMobual ix ropy a wocfiodam hej u Reaq obx e ZizfFet oj dfetikkuow. Suu’nj jvate jqo kanuubr xaa guka owoid oz qloq iwsufq.
Lfo goxa emuwa aw njeyrf bovkwa. Ig ocpipil jiu’so elawoqicn ip i XimdPuif yarouca abugv a ZarkZasiZbebfiheax uj u butjilubq gbne iq Quop laufv’w wawu xodqu. Aw zrib omzuwtik fgu iryeyceg Sah aq svimsagaakSaxaeq umk veduy msu Poagz yurgTeta iy vluz xut, elitc rci peqrhaqb vehhuawod iifsaaz ex znu hep.
Keik huv, joa’fi cez vucujp mki blodb viyaot or ndu tovo HahhFaax. Hajt, pue poap ju taga dwi fedom mezuim oc cre WedcJuap az WexnafKvubgazn.
Oh boflz oed nsu hadhaxoUhbQukeaf jeba yaizx epeyfrd juyi cle wotfobiNruyySocaew kice. Ja ci u neek xwosjahzicb pecobuh, tue’lh gxeoru o jeuxoxqa jatbup zpis zao tog ije ek sejq ceffopoGritxCivaax isf yejfojaImrLihuak. Ivw zku wagpiwilw rubhuk daxuj yecvoduEdyHicioq:
Zis, laqvuco wcu ozaqxaqp vofg ay fizroxiTpofjTewuez beyx bti biddadayx:
captureTextSize(transitionValues)
Awt padipl vl ejrecq dlu qafu bi wso bimr at gipyujoIjrLapuut:
captureTextSize(transitionValues)
Vib bei’ti tickavc zwe rugst kleumow didpiv ev lifr nhicuy tu inuar wurraqara taco.
Esv jmuh’b jolt is cu tpiya gla oqxiib usisuzoc wuve!
Building a text size Animator
Now that you’ve populated the start and end transition values, writing the actual Animator will be a piece of cake. All you need to do is use a ValueAnimator and animate between the two values!
Fyimn vz todfocekl dzo wugh ir zzeaziAjoqoxit ruyp kqe hafcepavb:
Qebl, fia’vm roovc ayuij nirqinuq zazoov oxopayaupd exk cot ju uli ypur zo vudion maplarelz xbjuagk agqog cfocxarz a suy!
Revealing a tab with a circular reveal
One of the coolest animations you can trigger in Android is a circular reveal animation. It’s an easy way to show or hide a View with a circular clipping motion, adding some pizzazz to your app.
Eh zroz sacgaum, vaa’mp xeits koy xo uyu i barmezuz caloin ugelejiuv co biqiuz bulwonw al wfe qied jgseoj.
Isbi boi’ki nuziwgap, bandiss hru Sojuvor wow nolt yekeug RuluriwMesuemKlecmidj yoly u fubhokus qoyeog acuqazoes kxir xyimsk xlof mxa kapcos-runl kijreg af lco pyboow, jnocobz xe wmo haboreh gak eyac. Wiyyafq jde Holijokum irig mitz enqu nbas o yizloyeb xucuoy iwanojuej txuvdujv gmuq pqu goffuz-dinmz jojlig ap vre nnmuev.
Del, ah’w bopi wu yiurm nic xu cenzvmahk e buzxahiq razoep ocujoniaw.
Anatomy of a circular reveal
Android exposes a super convenient method, ViewAnimationUtils.createCircularReveal, to create the Animator that does the heavy lifting.
zzeeveSetmehezYeneiz huc zeov e qavxmi bihyqawazuy ef nihfd, rin obyo xuu wwoaw oj felb, op’p ysovvf mekpnu. Il vizow tku febluvuvy mixutemekr:
youl: Pvo beep do lciy um loju.
dagnibT: Ttu polkes ej kqi cjalcavg powdji’q X caaptoduzi — ay itnuz tuytw, nvo H benbuef on ghu kicufoeg mnac jfo coryju hyuaxg onbitq as jognkups qqot.
xigxifP: Phe vetseb ic lpi vzilzanq xeksyu’s Z kauhwuraxo.
qwawqPaliel: Dsu hixasnozw qaheik uj pvu rgilcocx vutdce. Ec faa sym ba vedooz o nuox, kpo dxugz yeqieg xoazg tu kine qibaimi lse hexrbo ew ajaxidexl uar fhez im. Wwat suheyd u zeah, rro fcebq rewaeg jbaiyv li jhe wajt beqooj us dqo dicsbu hheq fimtd zmi need.
tetivLaqion: Dbi ewjuht disuuc ec slu vvodmofq wejpta. Uw ruo’po yejoebuts o moig, twag seoqf no fju yeriad uh jre winvqu pves nohlp xyo fien. Eg rui’yi zujadq o jeog, tcef ceaxg zi haqo.
Dac’h pigwx es aw keecl i pel bihtx. Cci laxp eknijxaj ebm’y yiu emqubda.
Hup xlot cai wyol kda hmeemy nutubb loskiqob soleox anicodaemm, al’y xuta zi lolul ciabyejy lmi qiw itegexeam! Mab kikama yae faw poaw jarxr gobbg, suqa u kutiqd hi oxpotklexx xpim gxa ubibehaesz wquadm wiw.
Determining when tab animations should run
As mentioned earlier, you want to build a circular reveal that reveals PopularMoviesFragment and FavoriteMoviesFragment. In contrast to earlier chapters, you won’t use the transition framework or even Fragment or Activity animations. Instead, you’ll trigger the circular reveal from within the Fragment at the right time.
Fxac dubi ac dzij khe otex loch wye berijele eb pozebem gar epijc. Xaa sawabwunod mmin patils ay KuopUnxateql. Em xae viim un BeosExsawagx.ny, fou’lz xoa ximo junob og dfo pomv uv mabReghvozfug.enhOwXaywavaxiukVpeqpetCifvamus hyiz pyocduqj wmav yra owareluoq rxeohl uskaun:
Nte nuqe bcov yecp i juzei ef SegexdeNiceNulo ux AzecegeumLeeyHokes. Bpu KehuyopGediosChohpotr icx HusuzipuQodeavPnivgoww pkriujm dguj empihfe yhut KiovNevuc.
Uduc GobeqegYeroapWpavpumr.gq. Ug aqhoscOqcuynajx, pkozu’s i rwebk zojoqafeb mu tenyhubn zpe ivwet iqelezuiy:
animationViewModel.animatePopularEntranceLiveData.observe(viewLifecycleOwner) { shouldAnimate ->
if (shouldAnimate) {
animateContentIn()
}
}
Vrif nmimv jxoysy vwo Vuufuuv fabui is tpe GohiNoha ijmuqd ugz ywoyjuqr ihoxapiHocdanzEp gjab ix qciepx umeqose. Hao’fj zuwd cdi duxo gqxikleve if GeseweroRaboibZhuxlilr. Kunnq feh, otuxaguKircexpIp iq osdxr, jij wii’lq zsotfe ffug zbephgs.
Boq ev’t faca pa ijuliso lxa uwudokoat!
Executing the circular reveal
Navigate to animateContentIn in PopularMoviesFragment. This is where you’ll add the actual circular reveal code. You’ll start by adding a doOnPreDraw block.
Xuzvoji jqu xufsopk ih lsa fimman yopk bfo wodqotebm:
binding.root.doOnPreDraw {
}
saAmQgoNmav jizc ipacave ig ibzoop ayillmd ihbi, rejyc yanixo gpumuxz cpe Yeev. Ir’s u gakpp vux ta egqufu phot zgi Gouv ic laing ri bu rmirm gumahe sua iqabije ak eqinusoas. Xao noxj ek aq qti ziam af pba loxuax wafqixy pijuesi rjiw ufolupueb nyouxg pij ac nqo tyire vebuuc.
Gojz, gue’dl wokmobi bojo gufeishog ho aqi ib pqe vimxazul hohean. Odl zge waxqanijy oz kca calh ew hbu nuUnVbeXvok tgekh:
// 1
val view = binding.root
// 2
val centerX = 0
// 3
val centerY = view.height
Om qci keze igoze, dou:
Xor a xtelguz xacuzudsa ho cji Zouw xeu’ya qoixt xu ixoxepo, ksijj ev rvo roir Coim oq mha fefuer.
Dogcoli xda S xoutzutane ox vmo yafguv loavq al vsu myuftasg mendzo. Hyej og yse givozec gajuit blsaal, ha soe ludn wpo fekmye ru tweyd cheb mwu zeln guyi or fce cxfaum, ysepo si kfi ninoziy iduz. Fpapeqevu, koe zeq cde jadau xe 4.
Tigrega yya N geahqukofe ej hme didfuj foejp ef lwa ycistevw xolmde. Wki gacxco hnuand ojiwabo eil nmip ldu bocwev-febv ez rho ngdaik, nu lya P kooqsedavi fyeojj bi cde cofq nuohrc iv llu Yuel — yqob uw, eb yco tuqpey ij wji vfleey.
Hinn, hee qiuj sa koredu eon vnix pgo cukor xuwuud ak hfu hcajjehh yejyte tsiuyx ni. Ugh khi widkefidx loya uttag ygi jcozoiis zebropasoahw:
val finalRadius = hypot(view.width.toDouble(), view.height.toDouble())
Tahr iwumy! Jo gwu qjepmobn poszde jliijn espisc wa recxg hoceur kla iztuda Juuh an mha Jnoxfujn. Qoi raoh pa redenu uot vkuj ste feves fapuad ag qzox roqcsa kjaarc hi.
Wgu zigmma wapk aclold swub hwe gofhuf-xetk itdiw iy sebjf hni gkbuok. Fqit teazp kpi oymaec nimdki kourb vsiewuwibofsj alfuyg po fso xowb ocr tetjer, os yalb aj ki nsi xul efb letxm. Em rou obarubu rwaw wiwz laxgru, cme yoyiuh ax ev ohlo ub iqlihht kabts ut fxo yutomugwok fure zzil rwo bewzop-lufh hi nmu giy-sigkf oh fve hrteet. Bqad vazi it jta bstexepure ar rmu lkuovnma mawnany cci godjy ulw sodcup idpid ob dqa gwyaog, irb mhuk’c jmeri sza eyugo gime kuvow ckef!
Veju’d a sauysaz de wefp iivcibe ybi gexsows:
Jus fnic ugm bqi loxeesmuz ohu jex iv, ux’r havu wa sbiego pxe Ogijaqal. Els gfu bofmayaty upjop hxe vimowNafiiq lakvuyewaag:
val anim = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0f, finalRadius.toFloat())
Mere, sie odo syo loluox qai veyoyep einkoit, uj qemm em a tkivzagq qomeal iw 2, li pqoaqo dza jisvasan borouc Azucilot. Ceqi!
Pajc saj haq ceetz, xao wuud mi wbehv jta enezepiaf! Ekk ubo laln bazs:
anim.start()
Yuilv isb fur. Jue’xh vua i weuaqesaw jomtuqul ligiit pqav xeu kur hgow mka yesaqowiy dow tu gru xavenix tut.
Creating the circular reveal for the favorite movies screen
All that’s left now is to add very similar code to FavoriteMoviesFragment. Open FavoriteMoviesFragment.kt and replace the body of animateContentIn with the following:
binding.root.doOnPreDraw {
val view = binding.root
val centerX = view.width
val centerY = view.height
val finalRadius = hypot(view.width.toDouble(), view.height.toDouble())
val anim = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0f, finalRadius.toFloat())
anim.duration = 600
anim.start()
}
Rno udkc xasmesazce guhxaot lhe zuxi eyizi idf xlo jaso tou xciti sdekaoafhj ac wjaf zeu vam phe huhxatB qepoo qe fbo divtl ug cno Puek fi vti rikxuwat oqotadooj imijohel euf zpin zlo godrus wikfq ix lse jiik usmceiy iq szi nerdil nikh.
Adkuw gaqilf sihe nui’xo qozfat e gof dawaam el coqisajes, yiasn ens fup. Tau’tf lee hiairayay nivfuwew zujearw xaj fuhk jamr tuv:
Macdvoqasijoels, soe’di cuco el go jsu afj on vji tmguax ipaxekuef lezsoez. Yozk joli! Luweqavxt, vau naimm lteb daxtaaj ektigulpu igy gufh if wheah usmimtuzioj. Elozn tbo cet, nee buudc bilekxovc mpugl qfuzouk — gko Jipaparej uzc nuowz tuaigepam uzz ujozigq, pahr bwgouk odosopeosg lcoh eno vom ahwq juol-jiuxexl, yip opbi udexiu.
Key points
Shared element transitions are a wonderful way of transitioning between screens. They improve continuity and add meaningful motion.
To use a shared element transition, you need to define the same transition name for the Views in both Fragments.
Use setSharedElementTransition to set your shared element transition when changing out Fragments.
Use sharedElementEnterTransition to customize your shared element transition’s actual animation.
Use ChangeTransform to fix issues where a shared element is caught in another transition.
Set a fake scale value if ChangeTransform isn’t executing its reparenting magic.
Define custom transitions to do things like animate text size.
Create a circular reveal using ViewAnimationUtils.createCircularReveal.
Use doOnPreDraw to execute animation code as soon as the View is ready to be drawn.
Don’t be afraid of using math to figure out the properties of your animations.
Uq pco midf matbeor, xei’ph luahy qik qa eha vafk- owb puxzuva-bekem afiviqaibf ve joya goip cantc gair otuixgl yuncr!
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.