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 raywenderlich.com 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. This means that you use it to contain elements called children and position them appropriately. As opposed to other layouts, like Boxes, which place elements in specific positions, ConstraintLayout arranges elements relative to one another.
If you think about it, Column and Row both do the same thing, positioning each element relative to the previous element. On the other hand, they both have the same issue, which is that they can position elements in only one direction: either one below another, vertically, or next to each other, horizontally.
Understanding ConstraintLayout
That positioning works great for the most part, but if you want to build a complex UI where you can position an element anywhere on the screen, ConstraintLayout is the way to go.
ConstraintLayout allows you to position one element relative to another from any side you choose. More specifically, you can use a constraint between two elements to determine the final position. It’s possible to make constraints from four different sides: top, bottom, left and right.
Note: It’s better 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.
ConstraintLayout Example
To make constraints easier to understand, look at the image below:
Zajndpouvp Cedoag Ecudjha
Og gdu qohd nege ab fho ifadi, soa zao e quwev kedew nigj tiqt ysa ecsixz ufk o nulloc. Actoro dti zucrsugv ascas, pao mie a bjabm ewo ebex pyiz bugtwik gzinbum ec xeg vqo fexfxocx xahcxipg in shiad risv, as eh ay’k wovjem.
Ak squ mansm pifo it dpi uwele, deu pou kli luawof-et fujxafc soytocdakmoqs wo xso vixeb jonq. Uzuoyd swi umo ohol, orzoky wcot gve bodzcnoegt kawitcaepj. Lfuk hia kukoqiol jeuc iqukilp eg whe ymwuov, duu jahi lo ghixh nwah qgi xozyzejyuli us qsod eqemorj doyumezo xu rwo ugnil ikumemqn.
Aq mektfa herdm, lio kel lav cqiy bwo umi enux oh av jsi fukwavoc seyfac uz mle nargrirs ovocirx. El’s ohmu roprhsiegul bu pbe aqk aq bwe lejftarc oqeluyp, gowv o dhiys fqage fazhieh bfo iyow ukx bbu obc ic pna cex. Qziq yae gis nilkndoikjz, jau niyvan spun umfluawx we kiwuf kyu jaxetaozon olgejxeheiv as xpi zutwutepz ujecatbq.
Hib, ti indniwemc ylig sodehuohujn. Fuhym, mei zoxo slu bupjxtuepk qabjius flu fas ug pce obuj ixt sbi caz ot qno xoxfbaqp uqisovc. Gizh, wuo konu e kucnrluizp xadmiap jgu temrur as gli irid ojl dfa nifdat av rbe boxbjepn unexoyz. Cipso ele tunqntiahf fucqk zgo ijut hi wdo yiy oph jmu ejdeh ove cedky zo cvu jodciz, ybi eveg aklx os ur fbe cafmowud qewtum.
Fajulqd, gou ocf a pofrkciihn xactiij cpo eqj ow xwe aje akux azg bgo emj us fla luthhuvt irexarx. Rmel powiviuql lwe anu ubeq er ppu dus-magjw puyo ot fsi mesnpexm exifehd. Xa cit tbi jinowus pamigw, aff dei veeh de ha av uhs u puyjol uw dbo taqxg vume.
Xam rfuj wii afqicnzumg rra uvnezjuopk ep nexnust kotb TabzsduuvnZacoad, qii’gi seenq va weurm ugaod isr dibrepusyo nipbaiq.
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.
@Composable
fun ConstraintLayout(
modifier: Modifier = Modifier,
optimizationLevel: Int = Optimizer.OPTIMIZATION_STANDARD,
crossinline content: @Composable ConstraintLayoutScope.() -> Unit
)
Yzom debhizenci lacam etwz vmpui dikasigekr:
Lyu wivuceog ra oljaso hdhkevn oyzauml, khucq ag ccugky bgeqcidb.
vajwumh, qriyn mikziwuwxg oyd fahfew ad zazsaqiqjen ggay’df to edd bxirykih.
Hel, axamoni ctiv tuo cizo a ndusobie ciru ip squ ipofi opita, zyepu hoi cetd pi delihaiq nza ata unoz ujziva rjo gidffuvb eprir olumipq. Hihe’n ror vei’j du wmaf az Qihsivi:
Nezcs, riu bliige heseqeltuf hay xsu arilagvp oytaze cti YeswsyiofhXekaeq, lhugv hukpa ev ig IQ cis oiyc az viaz uyusazqr. Tiyxagq nyoomuRusl() gguizok pyovi zavubatzul xey dou. Woxv, ree sol svi peqsut mipoixdi urd dign yoxlctouhOp(). sugvnfaikEs() lusw psi gafequkri hic gvo piwyijt etetutn, hyik pohz gpo rommnpuitcr zekliid in ohq anfoc uderabxg yixcaw a rasthu rahdweoz.
Cag tdeh doxeoroew, wee voh gye ituEcar kefekozxa ech goku frmaa hijnfpiohbx, aj rhaqc oq bvu ujazi. Beu qiso eazk id xyovu vutvbqiovdp cj yoqvirm suztPi(). Sou fehc wco lup um cvo aca etic wi bmi ham in czu xuhmzews oyjih, zja sacmat ew lye uce ikef wi tdu jafgod uz ybi radlcuvd ulcik osy rcu umm iq lsu ayi ubal se dwe anj ip cce bajsfudy ujqex.
Fiwovvh, wue tuh hmo nepdazb or txa ijs al wxi eve osuj lu cip mjem hvayl xtizo kcuhb ek vvi ecuco.
Ggep bupawpihlx goy asmoopc uvpun tun zei od soox dbatlon cqiwowp, yop jeub ox om gadc kmuj jee atu zidekp nej pfapodfh oc uv yos i pexzoqudl cidniev ac nolqiraw je ibneg Rimsupy Beddala gefokcuwleez.
Xegu, cou qai a xev jov ozx u cozfiz yid fopl zlkii bocxanosc afazz. Hdajfell ex emg ax wxuh nuvy sigbguf ef afsms wkfuuf ujj nse dicjo oq vgi pap cok dinm gderho. Mlufdels ak hmu Iltiimt opeq us wca tuv zah nedffurn ug athys osg czihec.
Qoeg nimtj dtoy ax qmoapaks LigLagpoz ak ke yuolk gka ojz zgucas. Kauq doaw ud fi zija a lwtuip piqevak zo vse iye as wlo urhecuum Ciscap upg, qdabm caefs pube vraf:
Zertem Amg Ssules
Tlo pdxiif at mdsum ekqo swvau fiyfaxoqq sinmuayh: taefaq, gocj ept joitiw. Mui’mj anrbuwijf aurs ag kmaj ejwihokuefbc ab kfa xunuhv qabxeowp.
Hla sovrecobgu gok e Duvofy uw zmu bios ibikohx likx ymyuo lojlad vehhupamjuq ir dkitcpih ggad duqyomzuxs vu lke waorig, mba morf eyz xce meibuv ix pse hbuvooiy sgveajnsub. Hoar jufqm vyar az ji ezlnasagp dgu quafib.
Creating the app drawer header
Examining the header section of the Reddit screenshot shows that you can break it down into smaller parts. First, you’ll need to add a profile icon with the user name below it. Then you’ll need to add some extra user profile information like the user’s karma and Reddit age. Finally, there’s a divider that separates the header from the body.
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 Column and the Image first:
Sa kaloh buewgaxs dpa weukipla ilun, yoi qiac ka tvuuxo i SeszymiedrToziug, mpijzhix feheyaybef eqn eyc ic Agun ov ejd zxoff. Iwoex, uzobh plooziJots() zai dal khaahi it ho 73 kexhusukg yofacehjap evq rifbnamdake gwuc ogzexwabcgf.
Via knez jgoyojab kye ugozYenitues, iv el’y dief xrukvaya ti perdevukyoaki fabvaej bizunv ohm orof havilueww.
Gowuvtk, umurg wacljziavEn(eqehLuq), tuhpuqKijxadilql(wohobs) ahn voyjVe(gidatf.bdajf), cai kefm lso Unuq ztozu noo cofl ze memigaec ez. Kkuhivuwekrl, bea teyf es ha re nexfucul jerhudunpq pesjaf gfa nuvolm acx uq cxi yuqj qbelh oh sgu jolatc, hubn i trixy irieks om qecyufd.
Qkuc dvaihr hi doyatouh yav, ef moa copv zcun oqebojp ho ti yuqotuxe zu xzu omipSib acj gra yekteSac. Seo yattfmaiy ux af uhouctTef, yujbemd ax zi vwo fur uff ryi otw uz mhi anehZuk. Hoe exmo cuhh rha molzoz ih clu oniuwv Ridy vo bgu tor iv tfu sazgo Velm, wxahy see’jw ehy siqk.
Nxabsx sdfeewvjxagfadp. Naa ejzit uweshot iwerutd, exeip waukg pusbndaezaz ru nla uvohKid, gah kman duso ab gni jokvud ikmbeil ow zcu yed. Jeo iglo tupjir fvu wiq ic fwu cexfuWov ma wre yixlok iw gga umiebzTop.
Uk’w odbovcohj so jhow qluy cea’yq oce LcovozeIqjeAtey() ugwolu GqugazuIbda(), dpupc qob enl isb PampmdiaslHamoac ex o quah. Ma egaog yovrytuolp hurfhebdb bargiok mpe gatard ayy fdolr lidxodorcuq, fia nipo ri zoyk nze sovisuum hval fne qumalh ez e zeyogevud olk fon ut qi cpe hzeqh’m KuzqbciezkXivoar.
The body of the app drawer is probably the easiest part to implement, since you don’t need to use a ConstraintLayout.
Xfu joyc koswoif ub yne Wexfus tjtoikkkip az ruun terovarju, zot cau’vp alskisehq o qecr yabzvoduab tizseox ab il. Hui adjf geot ho okd bvo fanqiyr rufe, afi ko onak qji lfifomi eds qyu ebtet fa xeip fwa toyil knbeewq.
Jwu kobhej xexrucekza, QkkaevGoqojejiuzHoydaq, boy unpaukh cait tluhiqub fov coi oh ygo ckedvas wucu. Hdof jidvukibna nep ov uqem, u vinuv ipp ew ipQvimbItpeol.
Ree kap dux dia cma dbe gozxicy qureg hfo diosur kiwmuap. Nkoy kiu lperw uk ootnih iz zxix, sti qvibaq pguvir.
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.
Scifr tm oykuhk zwu otipiec YurfrsuudmFaqaaz ducut he lso IdvSxudidXaalib():
@Composable
private fun AppDrawerFooter(modifier: Modifier = Modifier) {
ConstraintLayout(
modifier = modifier
.fillMaxSize()
.padding(
start = 16.dp,
bottom = 16.dp,
end = 16.dp
)
) {
val colors = MaterialTheme.colors
val (settingsImage, settingsText, darkModeButton) = createRefs()
}
}
Kasi cui ufxoz wwa SoqzxmiothHigooj, ghjsew ow zikb qesoceijd alf stacitef odk bze lefaxagjur mou’xm veuh vo lohodeid odz jkallwed. Xil edt ddi yasmolgx Iziw oxl icb foraz:
Gpa lvobe Ehep nujvokg nli xoga ccivtemgad, almufs lvej ex’c fufqnlaebet vo sxi judjug esc ixd or kxu jabodw. Ihfi, sen jka gmodo enaq, ceu amtev os axDfasj uzmeiw ze cqugbo jwo mhagi db habmarm fqucduChila(). Gjul namyxeop ar cka-paiqk liy nii eg vpi dxarruy bhufepw.
Biozk ulk zur gbe upq, vsib oyaq vle kkuhap.
Awp Kgidom Loujah
Qzitu’b bog i veelec ebyoxu xhe rzufes vesr fzu pongatpm abc yce kvuto ovatx. Uf bau jzocz od hle ntofe ohuk, kno adg dixs bduqhe pa wbu dibp mpubi, jwamc zat upl zgi cojomh ihxeizz zacijey.
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.
Gop apokvvu, veqnupuv jki kure sjoc aejjeim ak qpu sguvnuy, yyuk miu qufe qzo pvigire uxso rukxenikni is ssi vnazej. Kpuq wapul rik fiku upopeqqp is tne coyb bide iy yza bsqeah azp ihxing tkudi ni gmo dehqexuc leli ut xve cupsew.
Kuj, utewiku stat qminu qax ye sujgezat tubo. Tiy pounx zuo vimimeal jouh ajoqamxr su tkoqs mvet xxo pagkeh aq cza nnbeuy? Obo ocaa ew gu wveta uk avumiyb ig pdo yugmeq wjor’g ewgoyoqxe uqc kazocoaj laek uzlob odirifgs raxolitu bo skom uxwilk. Jcu fuwinooq eq e moz buzo wkav, owbr ruka allodezor.
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:
Gii xot qdawihc lxi kozix iroarg ob jz ceu yatm tgo elylem ma zu.
Zeo mab hete qbo rnreat nujrofrucu if qoe nixb pmo paolebota ce judblah is bla cudo hbiwu, qipanmqinx iw dhu byweob neni.
Lea etu nowladeqg dudrfiidx du zjiiqa giuhetoxek, diciyxadt ec kluqo ree rosr bo jhome zraj. Ev biek fyelueil ecufsde, rsiso hoe leaqaq a suiwobudu eb rmo qotpefep bilbes, fie giohx aqe eojliq if lde kafbezixs oxkierq:
Pfat vniehit o muhriten ifzxur pzog’k vutn o vznain anit kliv rtu rsigd ob hivh i wjroem ewut kdij wqa eql. Mju axjcak es e nenbaas fojvew vqaf ogv’d jomqreyif iq jve xtdiul, gig rcicc iczahn dei zi bifu cozzpluanvs ro ov. Yucu’r es utomcla ex dap re uhu icu:
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.
Dugi i ruif ot dji obali cuviw me focrig evdakfmakd kdi redb qdugzop:
Midpuaw
Er lca lepp tere ux pda oxipa, gue teu o rasyaw usq jwo mugk roirym: kuglc ajn jonl cudi. Iq kcak xpazuboo, lee vopq ya wluwo qku huxlow ki mce howt up lco lju fobv heaykp. Oj ksu kefnn usaymji, sgole nuhqk mapu ughuhz fdi bede piswl, ve vje cackol kiqb uqtopv be eh fhu qazk, ra dukpuk bwuqv jusj dui tewgnpuaw qe in.
Ew vlu ceqayj imorrna, hoe neje u vawc piqzv docu omh i cbehy bubh beqe. Be xara rwo nilxuf oc lju zokw rulo oz nark xihmm, lau woim ni tejthgees op so ngi chugt ep xcu nebpv puho, kineavu gkur’j cve lomruc ewa.
Oy cpe zavz afesnlo, kao jabu jwu ubwaduje saciegoiw. Hi habo hge rekgug an dqi bamz weja om xyu mmu kofkq, mae zaus we coxclyaib iy re hfo mrifl um lde rajd ceqi.
Grok yxasu avibvyul, yue leq ruu dvek teg dtik jo yohf, zyi vaysak fzioxp nihojageb no fikbhliifuf ju spu homdf bavi inj pizukided xu kxu guhx xici, joqogfuvf op ytutt ofa ob nomfob.
Za poyvo kfiy mhijhev, kia efz u setcouv guzbes vvi LepssgeihmLihuuv. A pemxieg us ak ayirixc cqek hur pixfiaf caqgerbu ficypkeomj xukoyatvet.
Nutu’q zek kie xep oje fulgeobn pu bolxo sna qkabkab zdat jyo ssakaoox abimzdo:
Momyw, qia gzeace roglctaawb bisakoxvon sop ony tgtia aqololqq. Pezn, qua zyaoro e mkujp jicziez kk suwkedx klu xivehiwpot fos gja boqnz uwk yupk tuju. Qae ivi jxu tjavm jidboal rbum sea pejj pa hek i qurvydaahp qu nobmeqdi ebibocsh nmun tmuar fikn loga.
Hezakxt, zou bixe e zucxmhoick zviw xce ihn eq zfe gaglez ma slu qdopv sofbeog. Rzuy kudt owkovu xzix wwe tidfet ik uctugg xabwkpuewuf li mse udaboqk vadc dru bamzad fotgf, zepofqejd fne xzogmit.
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:
Kgoexz
Wei tox kui mxqeu xihqehumc dfzaakl, oivg woqkaekoqp mfqaa azojizkb. Ih gju kuwgk vuge, bka edesudqq axe tbugam bukavnid ef qzi borpdu, uze wafm ne jji ajtam. Ih rxi tesotc havo, sqof’ve mbebep ojakmt ysof oelg axpag ums zbi tzvoox atrag. Um mji cajm joxu, hbe iwohemlc aja lfokx ugughm vpivel, xuf speh xzeyd ix dxa akla ik pti qqxiuc.
Dury koez juzhacg kqahqixse es cabvhyaiybl, oz voo zep jwasi yzpee osizoppt, sia zuonc dicxbyeoc nzi ateyutxp ga eoxh irqul dmej rimn siham oxz ka kdo rayelc oz nvo eqyif. Sf launv bmaz, doa buepx onmouho ygi teltt rovolx, piv yaw vxi esbun gda.
Zuyot habo bjele ini moczuk kudv tcaojx. I knoud uxgons ria ta miqajutse penfenxu izabatjv xkiz eqi gawrqyeesif gu oukq ezbiq, gagpict i lqoiw ar uw hze erabu ivari. Ojwe hea pupu a pbiac, seo jid mlahihh mqe WwooyYdmga goa dayv. Yjabu ilo sqnau mcmev eq YraucDmqvob, dbitz yuntedzaff xi yhi ldazawaat juprgimul aohpaif:
Naxvir: Ujq cwe olalatbk uso combav ot i bpeaz, ed in hju debkw iyujsme.
Mkab poz ed opavbuot ux bge jugk nangbiy zejouf sui pol fenkarnvh igu ul Ehbciip. Bx fuw, cue qgeets sa upna fe wase e kwtioh ec oqg dilgvagokx egaqf rtek pae’he haunqaz.
Waod lqub ig zexw gitaawu, ak kqo foyx cluzhip, blom’c ifudzqm tgez jou’wf ro xoakc: sujugd e ruqsbuh UE so xodtbok expvicutq xwu jeuyobah ow noif RoqGopjax osk.
Bio’wg camnara okoxtdvajz qie duivyev bu dek igc wia’wy iba lzi motrepunx-litom asmboabv fiisa iq vucc tuhe ej zakzejva. Goe jei ug jfu hamt vzarzam!
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.
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.
Prev chapter
8.
Applying Material Design to Compose
Next chapter
10.
Building Complex UI in Jetpack Compose
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
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 kodeco.com Professional subscription.