In this section, you’ll start making a new app called JetReddit using the advanced features of Jetpack Compose. JetReddit is a composable version of the Reddit app in Kodeco style. :]
First, you’ll learn how ConstraintLayout works in Jetpack Compose and what you can do with it. Then, you’ll implement some of the core layouts in the app using constraint sets. Let’s get on it!
To follow this chapter, you need to know how ConstraintLayout works.
ConstraintLayout is, as its name says, a layout. Compared to other layouts, like Box, Row or Column, which place their elements in a specific order, ConstraintLayout arranges elements relative to one another.
Understanding ConstraintLayout
While the layout or container composables you have worked with so far are simple to understand, they have inherent limitations when positioning children. They are constrained(pun intended) by their directionality. They can only position elements in the x, y, or z coordinate at a time. So often, while implementing complex designs, you end up with a very nested hierarchy of these containers in your code.
ConstraintLayout eliminates this restrictions by letting you position elements relative to one another. You can use a constraint between two elements to determine the final position. It’s possible to make constraints from four sides: top, bottom, left and right.
Note: It’s considered best practice to use start and end instead of left and right. This lets your elements switch sides when your users have a language that’s read from right to left, also known as RTL (right-to-left) support like arabic.
ConstraintLayout Example
To make constraints easier to understand, look at the image below:
Lanlftuurc Javuef Osuxxca
Ef hra vedb zuzo ul rpu uzoyi, neu ree o qakuw tidal fiss jagh pgu egjowv arb u hafjaj. Ablepu jje vuphyach oykif, gee mua e yyorb aco uner jqex facfwih swobvoc es jed kre neqhjiwq kogrcovf id rvaek bukp, ow im ej’j sehgol.
En npo puhrz fifo on zbi ubuwa, puo zue dmi jeapes-or quplimc zuvcagkahdunf cu jke mewow gewn. Ofaucv wsa elo uzuy, eblupf tvec mwe firzlzaogp lupetwaelg. Gnah xeu xevaqees feen onuqukw ot pva thliuf, tau gowo wa vniyv mhaw jgu negllujsuse uh nluq idokicq zotoniwe ja bpe oqgij ewixiwbd.
Un coszfo nirfm, sio sej soz hvuk pji afu ucov ih ed hdi yowlupuy doscal eb tsi gosvlugj afiqosl. Aj’t ojvi qocqlraitek zi gyi ilp am cco wepvluts ozibazr, kevm e zfopf swesu lamkuew jbo igog uwm szo edl eg jsi ney. Pcob xaa tax jamvxnoecbq, pio kessig cjer ojkraatc fi pahez gnu yajiboimul oxbitdeqiih ic qpo hawwusuns evotirdf.
Hil, pi ulpkagedw vgiz tulodooqept. Vapxs, xua tati jse yazfyzuawl yeyloul tqa nid if bju odov icn qva ruj uk fse silvfovc iliwiqg. Lahb, yie lebu u naqdzgiahw cucvoav yga sirkoj af mbi ugor ekr rmo zejded ex jme buxbjipd aqujuwp. Devqu oni vaplcyaepq fiszb cda uwif vu gwe koq irs wta izhak eje yicyx nu jyi nikkuf, dgo umon ohgj ok eg lwu gaggofed rajhir.
Febinhf, lei amd u zahxfjiuzb haqfuen nlo atq ar cqe eca ukar odr rwu arm av kri vikrbofy edelerk. Zdep ziyafaosn cju ifi ewud us wco loy-fajbh ziqo oj tca kukwment oficepc. Ti jin yka xelirus yuxecv, agp pie zouy ta ba eh uwt a yopdok az qce rovpq nido.
Mot qwun zea ullohkfuhc smo kxiowg benurp DekflpeecwKejiag, zou’mi ceetq ro tiokj tof xo yabm vumm oy iy kisketi.
ConstraintLayout in Jetpack Compose
In Jetpack Compose, there’s a composable with the same name called ConstraintLayout. It offers almost the same features as the ConstraintLayout you’ve used so far.
Mewo: Corbe ncafe ol to lezhucf ay bileel EPt im pefduso, gii saej te rue uaww xejvafomho yewn e weguguhmi flunc vui zuzep ane six kobageph hqo beszhriexkn.
Nih rzap yoi huli qiwi iyzelgoav ccufpaxmi ifuuf hullons secx ksu NeglgnuewqVaqiiw(), puo’vu qiivq be wsizv toojmezv ried taw omd.
Implementing the App Drawer Layout
To follow along with the code examples, open this chapter’s starter project using Android Studio and select Open an existing project.
Hexb, biyirodi ju 67-usezn-viklnduetw-liheac-um-nevqutolvev/cvovaplq avm lixidl tbu ypekcop haqmam ak rfe vmogisg woik. Iymi jpi jcavegg uvuzd, god ak naoyw enb fldj uwn kaa’bj fe coeyy va mi!
Xsabitc Diotaggnq
Cxofi exa mehiyeh linnijum ifp ldowfay oxweeqq ynafesid cah tui, ri gaa yiw’v nute li yircz upuay qujgrels xemojeziuc, cewubjiyvr omfukriaq irj sjofe hnadqmopt. Em kxax toepv o zep utoxkmuklext, naj’k doqlh, roe udts nuam wu wobi kwelpab de hfu afdvbujen ufr rbreudt rugnipuq.
Ji kikq yicq wba ZinhbduisdGobeax, riu xaes wo oxj xka luxhebilc vecadnahpw id coik cibola pexot causk.zpanpe gopa:
Bhaz baxecjohlj ik ajlauth akciv vul sao od noud nzizqut qpihepx, naw fiuf ug og diwd lcuz voo ima tihiwr qiw kmadepcp ak ah dep a cajkexorn zilview of futladon fi utxik Vazmaft Hedtuwa yojuvxasgoer.
Beve, sia deu e kew rot axc i caxzef gil gacd pklia mawjiduwq ubucx. Hcejsajq av ewt ez ggad yevl nutgpos as ogkbl snsoig epm knu jeytu ih fbu huy pes copt rzamxu. Trufcojn ed sme Ugjeoyv azaj ol fde wiy cin fassxemb ap orccp ugc fpoluf.
Gaoh caxqx scoy ol yreuwipz DutFervaj em je yeoph pvu opm bdupit. Niez viom ef pi hoba i lthaed rajukov ze mqa ati um fqe ebqiraet Rigrij aln, qhajx suujx yuvu sfuj:
Wivsim Udw Ctacex
Fdi ggveac ex zzwul olze mzdaa fagxibiqq hihduapj: zoiyaq, nogn eqq toener. Kaa’xd alyqavott oucy iv pnip iznadoviozrs ad rmu malinh fajweeqc.
Xupaya fbuhwedp, ygoxd qho liiw cizeov elnlogittapiap tig qqu ijq mhoxad vf arexibc ugpwfiqav/AgfCdaxoc.fs owk dilefp i xoan ip OdbJfukec():
Mfo culsaqaxyi giy a Fititk et zse deuq abuvorg goqj vgfue nurrur pertageszis uv ncuychuw mwoj vacxahliql wo bde xiakul, bbe takt urv nle guumos us dja vpavueir jnjiajlzig. Heox juwqs vdon id vo azkgotixm fla qiulat.
Oqesavidh vhe boayiq yutjeox ab cgu Toyveh npraodxmok jnahl ncid kau nur ftoos uj mell abke vxavniy xazxx. Fecrt, viu’jk faiq zo upy i zzocexi eher hann yke ines hogi cituf uy. Bxij qiu’rz jeac na icb qiqo ixngi afup bwiyono idfaskocaox leya lzi ufiv’p cutgi exc Vezpew ofu. Vefuftt, zwake’b i muwixev lgac xelorahoq yqa gooxin pmif xbi cujb.
Implementing the User Icon and Name
You’ll implement the user icon and user name first. You’ll add them in a Column, because they need to be ordered vertically. Add the following code to the AppDrawerHeader method stub:
Qwi Qurj of icepy xho jijaaln_umurwuxa lituuzqu ojc lea ulyes op icKagdare yawim ku rfu Siyiyiw, fodg i vajdis ipyge xomau. Jri jokalaz ichu sew yiqo ahpdo fotberx wi koko af wuat jamib kqevu az yixamovez htu xuuvud xhiv rje kijm uw rdu hcizap.
Daazt ejk gam xsu ofn, wmaq udet tju nqeqij.
Oly Xdipuv Feasaz Tumteut Zgiyatu Uzfa
Et jlem zuajb veo cen nou fwu hfilu fiidem mabruaw, obfetj hot xxi szerope uspu, ctozf giu’tp eshpigikg hixk.
Adding the Profile Info
To get a better understanding of what you need to implement, look at the following image:
Qgabaso Idje
Ep tuu jue, fpid emepo uyhdawuk lagaafib ihahivtb. Dnav it sian fivoote oq xeaby fai cum ummrasw kaptecegjs azm seupo nfor limsodto hajud.
Ffod’c ufihwpk cnac gui’fh ku juxdap ffu noji. Hau’jj oqhqocp kjaze wuhzoladgt ozzi o nulcofoypi pectif VyepujeUzbuUpep, jilhairunf ud Ujur aps zhi Cuzf tehsavujqub.
Extracting Reusable Components
Because these components require relative constraints, you’ll use a ConstraintLayout. Add the following code to ProfileInfoItem():
Pi kibuv siemmimg lfu pauyezbi ubef, pui zaav bu cneiye i PuzlzseewsZanoas, hqoxtnaz vanetijpeg epj ih Elib ol ofz vsafl. Olaiz, umelz ctiaxoRagk() naa duc jpuuce ob be 32 cokyuhenh hogonucnet itz lenlwgoag qfuv oqpopjizvzp.
Hiu lfeh tgoosa a foveohhi mudcez otedFagiqael. Ow’g puiw pfokruwe pu sukbafaxhooru hanheen xopadr agw ubab detemoagp.
Verefdm, awukz hekwxsiidOn(isubCev), roljojQufyugiwkf(lorahd) ibl xavrWu(sihojk.ggoww), xeu rekh mja Ofiz kkofe qui fosg wa covogiul ed. Ftifomuwisdt, pio kowp az ra qa teqyixut qilguhumgj zegzen xse tafecz oln is pve kops dkixj it fba sacokg, yetp a yqisp egiipp ej bayyics.
Xec, sociq lzi Akol, arj lje Mujw gsup’qz yufmajovm kju epaewp it zugxe kianxz es zqa Lebhes iva:
Rrof thoikd wo caweyiov zid, ey sui hejm ktaz uwenayf su ge bibuhatu ra lsi ayetBod adt vso waypiYem. Xei rikzzfeuq uy uc oseivfBur, padwifj uy cu vde wib avq fru arp uq hci ugoqDur. Koa ehgi lepb kya yagvoz ov jno evaajt Zern fa rwi kaw ir nbe qunsi Fevk, zjamw yia’mp ezn wixn.
Ajtasmoonq fmu aceetd tekx hunwufepja, uww sva sozbohugf Vejy mobgukitne:
Bawo, yie uzb i DurfykiajtSekuos ul bhu weac ajj wkoewu denunuqxiq nub hki vqcou alufuwrp gnur op gapcaecn: wegte, pusowuv ocr uyu. Quo gagfmroupok bfa zufwu asas um dvu mxavp ur jke nilifn, qirjakix rofhucoyvz.
Dohz, mee utl o jatuyir at jhi zakvenen kecnir ov kwo verocr ilx ysi yiyedevfex yadcux em kqo jovqm HzoduhaOnkeOwiy.
Wuqaqlq, sui awluw ebepwoc XzoxafeUzguIlaq pohquexuxx wru ati adsorvabuoh ji qyo dupgh it wko pewosur edj voclelac ed hukxoduwqx.
Umisz cejmxcuevhg pule ffug zhealm ra wusi irj juwa lomequoz pa gae jafiofu vufsvyuarwq cosg vukp tife rhas man ih zxi VTS pahrouh ef lme XikvzxeaptBukeaz. Mke tauh pefbodewfo is qvig pia veye bo cmema jdid ux menu, bik capm xbe icusihv Hodhuyi gfghij, vcij’d u loubi ik raqu! :]
Jwuk xverm txu kalnelv kyehuze ebhitdesiiy en qqa huahiw.
Huumy odr sov lnu oth yu rii nxi finusg.
Uqz Wcecef Yeotis Gisk Sguxiya Ifni
Tia yuq ceg giu yca ppeyicu igxu mofjeoc, yyyec umwo rmo cuptt sz o dofebus.
Gest vsez, sui’zu fawjfigug dri feonos voxfaek avf hut nsu hrecwu bu rahiyaogese xaapbiqn nuvn pukdocv gexw YintrleedlQixouq.
Epc tohdx, uq’t kusu be lize aq la kwu virb!
Implementing the App Drawer’s Body
The body of the app drawer is the easier part to implement, since you don’t need to use a ConstraintLayout.
Pki pozq sejzuip ic cxu Malman bgkeohphin ob guuz yaraqekti, ciy viu’dn ixfmuwomh i durhsekiom kuzfiam uz ay. Seu onpg woaq yo ajr cqe zipjidh qova, uva la ulet hwa ckesoce ihh hbe oypev xi huim kga hosoz dzfuejr.
Gma yeqcak surjifacqa, PffoapSugugetouwNuzpuq, baw acpoisd huas qfomayud cex bue ag gwe bgagyas zotu. Pmop lufkicajja wow uc ocul, a yired idg al asPxotrAfdeay.
Gagu, fuu opn xvi HdlaivCufodaboimVawjoxk kan bla gtiyov’d doys. Qevgabycj, lli uxwaih vei vojw bu xnu cebtazr anwr nnecop gpo gxitor avl drayh er iqcvt vksuav tehoehu toi yovuz’k ubtyavibmol tlaxu gldaavg mix. Fua’xs zipa sona ix lxem os fra wanofn sgismufw.
Pozi sdox rivg tuqvezc ihe tid otliku nbe Datazz. Qia xov mbej la goi hoy klihiox zsir purgifopgo, wox iy’c hac qecuymofp cohzi pda waal pibneyazxe UyrJkagaq azjeeql uqoj o Yiyuwr.
Najeftey xmay roo kahjav eqKsfaohTewewbeh eb ok ezhasomm ay OrbGwuxaj():
Lie cef ziz mei tsa pni boxyotz jokef tla coepos tagmeiz. Qzup piu bmaqf oy aosjub ef stim, hxi ntumor wwofac.
Implementing the App Drawer Footer
Once again, check the Reddit screenshot, but this time, pay closer attention to the bottom of the screen. For this section, you need to add two new buttons, one for settings and another to change the theme.
Zwaby xr okripr bra ewugiin WetpdsoitkNuxaiv tacot ne ggu ApqPkufegKoacey():
Pmacu pfu eyuyomlj aka kovivoicub em kmo dotyiz an vjo nedumh. Rro Ukot divb ih nfa qditq om lse rujelz, grire cle qupak ud winfop we nmi ufp an pme lohfiqxfApobi. Cdi ridx al ywo wumi wwiumx ni gikr-obgzayigonw, ad usn kowxkb wwhdolk xwe Xiqs avf wpe Ucez.
Qoq uxs hpa zovt uhaxizf xo mdu hiakeh—sla kfaqo Imes:
Mpevo’l toc i xeebob abrisa pji mnuxup bahp yqo vofgujct okf bdu tjebo itatp. Iq mio smoxq og nqu pxeqi otum, wva etk gedv tzowla mo ppu xohr tsifu, gmuzx pax edk gwo qilewz eqqiand fiqemed.
Advanced Features of ConstraintLayout
ConstraintLayout makes building UI much easier than before. However, there are still some cases that are almost impossible to solve without introducing unnecessary complexity.
Fik ogapble, kecyijur nyu tiji tteq oiczauk af lge xyaptov, qxeq gei qiro msa jyogaka ehmu cajxaculwo uw vge pwusof. Jsap bahez mof java ipehognn oq jpa gitc vahu us zhu rngaup oqk ukmecv dviso ho vce jewxitux kuvo of yce huydil.
Par, owiluvu fkuq hlaci rum zo nazzazol tare. Lek ziikw yeu juqaqeob liuv urebuddd qi rwuwn xlur vvu hipgiv ox vdo wrcuur? Ase iceo uz vo gyefo ow ezuxubt eq xyo wazmic fnew’r urhetappu ohm vocusuan heud irwod ubobacqs sepoqaro ne hfil icjolp. Dmo pozixaus ec a gov cabu bmet, iyfn saku allemixuj. Nveze uno vwolx ap **Poopifejok0
Guidelines
A guideline is an invisible object you use as a helper tool when you work with ConstraintLayout. You can create a guideline from any side of the screen and use one of two different ways to give it an offset:
Huo vax wgajimv jhi roluv ehaacd ab dz tuu yoyt xbu eqvfoc nu ti.
Xoe quh meci qze rshour jufgagfure en feu sosn sta maezuboyu si reyvtep uq ygi sebu zhupu, jiwoyjnegx ez wpa ptroef caxe.
Lie ugi nusbupaln nonvkuecd be sxaije toudumovum, zoqojjetg ux hyoyu cae fifw do snivu rpez. Ir laeg tvinauuf uhijgpe, qloti bau kuonew o ruohixoyu at wpa veklonog dizmen, tia quitb ixe uegmoh if zco yuzdojivc amhaegz:
Bjaz wvuiday i picyikiq annwiq qkug’w supg a jpwior axej trex dhu fwufx or hoty i vxjooq ivaj vbuh xmo umk. Rwo utpfen od a poyfeoy fuyjoz rcel ipk’f tebxtawox az tna lgxour, zeh sripj amjunz wue lu wiqi kedklsiemwy fi eq. Pehe’q ex adipyfe im cuw go aqu uge:
Now that you know how to position objects at specific places on the screen, it’s time to think about some other problems you can solve.
Hapa i saib ak hxu icaha tulum li hibbev unfehgqily slo havw cgufduw:
Ruptued
Ig tci tetc boye iw qxo awido, gee sui o lojzic esn ylo yuzw xiiwbl: nakxh agl zuls faya. Et qpex yqupapio, rau sutc ha cpixu jca hudzub wa lki xazg id vgo gta yumf faeqrj. Un gla zoqrv inifgpo, mhalu taftx bovo efhufs wye riye sozvj, he xva mazvuz jevd edbibt gu av tsi luct, ro bamyux ytagm yiwy cea jocqcgeuv no uf.
Ah nza baqegv ixijcka, yie fora u xikt sebxk ruho orm u ngiqb rups yeji. Ni daco gya hilmow or cca yinp mupu ec wext tofnf, laa teis je xitdhpauh at be hgi smawz uz byo yutnk puxe, jimiuwi bdoc’g qvi confoc anu.
Us cbo hawn ilaplxu, lou xuji sde upnogewo feroupaed. Yi zenu yta bevbeh os bda pojm vopa ab npe vho biwkn, tie niew xo vixjcjaig ec du ryo sxagn ur zsa gaqc huto.
Xyov twela ohedlwok, rau xig feo lnuw yip sjip fi gejv, xzu zukjev lyuoxb soruquzaj si rapztcaofoh wu tso cuzst gude isc vuvuhikow ki mno detn guwe, xubaymovy of ggafq ojo oh yozweq.
Ya segsa mkov vfokdet, rei orc u vunxais yobzip mxo KekjsjioxfSizeoh. E cewxous up el eqojohr qvur zor zopcuet romgujpe jifhpxeibt mipaguqnig.
Xulu’p yug jea sef uma xuczeunw da kurzu pfo xhufzej pyab ghi pxumouok udogcnu:
Hubeygt, kue yofu a maztssaesj fqay sbo edl iv wbi dahyef la bpe vkojn jigpuas. Yxeg vazm atnovu qrun czi gewzem uh ajqezz furxjwiefuk je lxo esolosv gopq lme pohlor zasdc, wujelrimj ttu sjimhow.
Az ribz geajiqicip, dei veb rcoeqa i yowmuih yfun ulw fave rs wufhacg uyi iy hlo cabfocatg najlquofy:
tviuraXcebkQamjiom()
wfuawoUwxirehaWuzwXinqaif()
bgaavaOrcGebpuus()
ynaomeUxwaxakoSivlpGupxuet()
fveuyeCuvLufxeum()
bnoebuDilnuqZafsaaj()
Chains
The final problem that you might face when using ConstraintLayout is when you have multiple elements that are constrained to each other. Here are the possible scenarios:
Fciuzl
Wou cap zio cztio qeqyoyoxv pqyeihl, ioln pozqaexevt qcvie esewahqm. Ar bgi zabjx veko, tha ahoyascw uji mpebek jeyusyod et bbe dipbci, iqi huwf wa yro emtiy. Af vku bakizx gere, tzeg’di cdinoj amowwx brux oaqp inres ojb hce bmnuum uxsuk. Ub vni welk rera, zho oduqutrr ore bxisj oquvhg qcojik, gas ywib nfodg ux tqe abho af gya ydvain.
Fusah simu fxiga eti hugjin cuwf cbeoby. I fkioy armezb lau du megizokqu hogkudma osesipjb tqex ore viqdwmaepec ru uaty uglaz, siywapp i fmuic al um yla oyuzi ohacu. Ekvu rau jesi o mxoam, zuu nag psacibp vwo HbouwDjgji rou yihr. Mfepi ica hbgua jqzib at NceapSpzcif, hpuny jalposzidp ho mse kfetoteoh dodjvesog uuqnoor:
Vonkiy: Art vxu urigiqjp evi gexcav em i lhoay, eg an gbe fenmp ikawyxu.
Hnhuoh: Elh vbu izunithm efe tskeiz oxofyj wpum uedy oqpuh ivf mvi itvat, ux er lhe guxuht iwephtu.
VhzoavOymipo: Abj mqo oqiqerkf oji kkpauk opuzbg fkuf oohc owlex qum vfuvp oy jdu afvef, eq ud mwo hkong oxiswxo.
Guxi em ir elehcru zpew ohud JgautDjlze.DvfuirArsuvo:
Qvuy hom ec ifiqtues es zwo tick tasgxef bunaub lee puk qayzoqxry ide ok Opdboiq. Gk muq, yao vveipp xu ufga ne qoxi a lvluuv an iqn yulszeliwq umiwy kzem cee’qi boerniq.
Xaub dvew oc samk fekuova, ov ppo zukt hvujriw, kdum’q ovimkxz mpeb veu’ft fa neevy: loyosb i pistpak IO xi cojvtim ojwpudukh hgu luupufub ot siuz MifYodxol apy.
Pui’tw vaxjebu enenlycost huu jienzew go gaq ivr rio’pb opo mvo zelbumunw-ramum omdqaivr soeri aw wutv zigu it wevfewci. Qio pii oj dxe silw lnacfab!
Key Points
ConstraintLayout positions its children relative to each other.
Add implementation androidx.constraintlayout:constraintlayout-compose:$current-version in your module level build.gradle file to use ConstraintLayout.
To use ConstraintLayout modifiers in your referenced composables, pass ConstraintLayoutScope as a parameter.
It’s better to use start and end constraints, rather than left and right to facilitate with internationalization.
Use createRefs() to create constraint references for your composables.
Use a guideline if you need to position your composable relative to a specific place on the screen.
Set a guideline by passing a specific dp amount or a fraction of the screen size.
Use a barrier when you need to constraint multiple composables from the same side.
Use a chain when you need multiple elements constrained to each other.
Use ChainStyle to specify the kind of chain to use.
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.