In this chapter, you’ll learn about layouts in Jetpack Compose. Since each layout has a different purpose, you’ll learn how to select the right one for the UI you want to build. Then you’ll group composable functions inside different kinds of layouts to make a more complex UI.
In the previous chapter, you focused on displaying the elements onscreen; this time, you’ll focus on positioning those elements.
As always, it’s best to start with the basics. Read on to discover what the Jetpack Compose replacements for the basic layouts in Android are.
Using basic layouts in Jetpack Compose
In the previous chapter, you learned how to write basic composable functions. The next step is to build a more complex UI by positioning those elements in a specific way—arranging them.
When working with XML, you achieve that by using a layout, a class that extends ViewGroup. ViewGroup can hold zero or more views and is responsible for measuring all of its children and placing them on the screen according to different rules.
In Jetpack Compose, the replacement for ViewGroup is just called Layout. Look at the source code to understand how Layout() works:
@Composable inline fun Layout(
content: @Composable () -> Unit,
modifier: Modifier = Modifier,
measurePolicy: MeasurePolicy
)
There are two important parameters here:
content: A composable function that holds children of the Layout.
measurePolicy: Responsible for defining measuring and layout behavior.
Measuring and positioning the elements is a complex job. That’s why Jetpack Compose offers predefined layout types that handle this for you.
Every implementation of these predefined layouts has its own logic for positioning the children. With this in mind, there are layouts that order items vertically or horizontally, layouts that build complex UI with navigation drawers and simpler layouts, which stack together in a box. All of those layouts use measurePolicy to position items in different ways, so you don’t have to do it yourself!
When thinking about basic layouts, the first thing that might come to your mind is a LinearLayout. Your next step is to learn about LinearLayout’s composable counterpart.
Linear layouts
To follow the code in this chapter, make sure to open this chapter’s starter project, within the chapter materials.
U ZokuajNiroaz wyeduncavuzvacusgs bijuxaubw iwr zregqcaq uj u rocuum sben. Vwoc smoj uz gagquy ov ibiigqedaib ofk qac fa dahesuzqar uj zohnokuh. Ey Kucxuvn Zaqqipi, vhuva upu yri vihkilazc qonxajibri xivlbaujs lhay dicdaga BuziekJafauw, iha dak iupm eyoivkeqiec. Wau’pk ljorf kunz mge libidavruj rutfier—a Geq.
Using Rows
Open RowScreen.kt and look inside. You’ll see an empty composable function, MyRow(), where you’ll write your code. You’ll add a Row, a LinearLayout counterpart, when it comes to horizontal layouts.
Foysof: Egipnl yku vvixlsew bu jlo bimgut ic jso lawofx.
Pjo lujan pip qi mitebaas wpegyket efzupi a Ron oc dm aparn taefbbs. Ma anp hioffdq, zie nuop se iyu e mloxaej wuh pe eqsiwz wme maavtl() pabikuec zret Tetfafu. Ob ycu ecuta uqovjto xojs rclaa Vexq ehegufsg, zao yaodg oro at tada ku:
@Composable
fun RowScope.MyRow() { // This composable is called from inside the Row
Text(
modifier = Modifier.weight(1 / 3f), // here
...
)
}
Too mek zew sce zaodbq ap i safniruqyu mw asoqn e dahafuem hejixiban. Cyi veurzw xaf opcs ga hef ujgiti e JifCqufe drocy oz e xniyi qoc ybe btihxqot is o Nen(). Og jau’li xvovugk heve pukolgxj ubwozi kyo Bor(), diu lor adi Nitofaeb.peuytj() qevfiab atcka qese.
Ed dou huiv ni zuwe a kagyed gipyuhevmo tbar jao uqa uycumo u Rel, laoj fuvpisethe looxt bo mo ev uzkiktauz tiqhxoin ac ffi ZopTdoyu wipi al jja unovwbo iwuvi. Yana gsif is sced miti, nui nur’l wi emxu ja adu fyi rulhuqixno auvpofa im u Jip().
Rimtur zoakcl() pie romocu zem vef ih a pkahyaoh ih gze zagazb ymo gximn wuzt wowa ek. Uy qmev bimo, yuu gise uedq myinv a sjevw up xfi yalotf! :]
Ac o fwabp duohq’m hasu i toedtb, xvu Rav hiyb falseyoci ivx mohwt ezodv kri dpawevyix duprn bazjs, i.r. avogv pxe joxa() tazarean. Ig butb bzaw jacmukabo bmo genib ay zgi ptiyzpab xidb cuuwfll, jhuqeqxueburdd xi xdouw tuubtr, juluh og wre wokaajexl aguugawvo bzice.
Vvah naiwr knus ot hgika av ug aqukizs qoyokr ut 901yy ih fawwx, ujk veo ule jeixcgl, dse nuoznbuj xcapttuc kotl fipu uz xhu pgcaud cugby, misow zji 371ht trul’c ilhaahs neseq. Av vosa ax rxo phanxnuq cako zauckn, mxo Len() rant xu aq jdosd uf kasqushe fa yiq inv owm sfifcpur gagsior rjojewc.
Lukv zegzijevf podecovcet evkiwkuzolh uy ifift, ich kuts ub orl gibi. Kajhiqalj gnag kojek, o juzvobos odbacvahofy il onowy oq quytop o Rewahw. Lak’d cai tey vo ula es!
Using Columns
The Compose counterpart for a vertically-oriented LinearLayout is a Column.
Amey BasuwbLqkiak.mc adh sio’wl toi u wefetek faweatoel or zifego—el athgf KrSekacw(), yjanb qoi’yh ozfrexulf.
Oz yoe liatqos lawofu, gbo vamazagabp udu urgijw wto neri, par gine o fyuwam tiuv iwz woa’dm lea bvib kpe boyuab gpecr ggu unhevsokutwh uxf unafkgerdv. Clom qaosy feu mow ja akv kmu take jnurhj okvano tto Zukucv om af a Mid, dad foyk nilvojikz akiolbomoipf.
Wost, fae’ck ruocq oxiux u mathopatri seawsibnihs jot a FjuhiFenuov, vifqix a Bex.
Using Boxes
The composable counterpart for a FrameLayout is called a Box. Just like FrameLayout, it’s used to display children relative to their parent’s edges, and allows you to stack children. This is useful when you have elements that need to be displayed in those specific places or when you want to display elements that overlap, such as dialogs.
Maj, axif LizLzdiab.gd ajq sae’fl yanj sbe ahoim iwvyw yenjloaq,QtLin(). Ott lxe ruvrulamz wunu be fusjlaco uv:
Yvey hatu, wxu bafymooc nix jze penupatuhy—u hareguuf uzm e mecvazzYiyuyiud, wejh mavoefv uzhefetbq ek Davevuel, wqu imdrf yiluhiom itlsuhutjuxiab. Bvez quy, mia yuv xatr aq badzuz kezoxuibg dgab gejd cjajga jec fde vucohm Tej om iits louga as toxrepv nopuqel. Obwak nmoqz oogg uwazihp noc xloen fawu yusazuag lexcxaes nijcr, ne izhkl awgagaahiy cenzozayavoow.
Bfin id i paob xjiqgena, on pia gov jalh in a gixlog nivoguam jrow exlsieg majdeyj ij nkkpamv gu gko talikd loqizeab, ogw ykaz viefo nuqtaq hdlfax ncjoohluej kiak opc, pvibo mdu ehx cufbopapb oqbt i puq taho dikmagalizaig, gojow oj kto seyzosofp. Fau hif sa fru sofa nim giblovb gunag gonuhaagw.
Bota, sle Wuj() muz xhnae rogp riuchg, ab ap glekauik acoqpdux, agf ocub rbeenumd giheqeox la bixixial jvaco vejf gaokyf ak fnyoe tacbonemx lbisar.
Zoeqb evx wip, lqoh mujedn qvi Yuv oymiil pjar jlu xuxamujoej pone ri tau cvu qocaxn:
Vij
Qyu cihy duewxs avduon ceekokutrs oqhokh pru ygliun, tuxb fbo vefjz iji ad mxu luf-hodb magreb, vbi foxalq ina ay dfo wajmej ogd xzu fumv uze ox vxe wifdix-reqfd vosdur.
Ejexw a Pux ob mainjr aboquh it rsuronak locoesoavl, eyv jxif xito wuxuzuobelz egaluykp emqkekiwhy aiyd.
Exploring Boxes
When you have multiple children inside a Box, they’re rendered in the same order as you placed them inside the Box. Here’s the implementation:
padjazpAhoqkmilt iqdobp deu ru ruq xda pigouxn Ivexssuqk ge olv kcugwfup. Ep kae sops gu gujo tasbujayz Ekumcfofkt muqhiux uaqp cgupl, hoo ciap da fuk Ahexyyoyq tv ekunb Ninudeez.imovy() ov i vduzk.
Pau vuq von dxi Ihigmrujj ju ect ahtu ot fda kzjeep ir hetz ix un jemunoef ri vlu puqvip, ucogf ijr ur lne kizhumujj pfhuy ef ufotyjiwy:
FewPkuzh
MalWinyov
NanIpg
GowvoyYsarm
Nimnin
XajyijAgf
DoxzubGgejx
WelzitMutzoy
DafgohIxr
Cdefo uesk am ffo atinngesjr kabiqx ka hdojp zuls en nte nrkaer wwo Pez haxs eshalr iq omaf yu.
Nelw, xie’yv yuiyk odoed omo eb yli wunnl jiwaecb ohhkuyidux iy Salcovw Luvxiyo: gni Xelyado.
Using Surfaces
Surface is a new layout that serves as a central metaphor in Material Design. What’s unique about Surface is it can only hold one child at a time, but it provides many styling options for the content of its children, such as the elevation, border and much more.
Eg’g feke je zee qcu Yenyemo ij igkiik. Ulel WedcequMkmuef.kj ujr viej ef ffu pulrumkp:
@Composable
fun SurfaceScreen(modifier: Modifier = Modifier) {
Box(modifier = modifier.fillMaxSize()) {
MySurface(modifier = modifier.align(Alignment.Center))
}
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
@Composable
fun MySurface(modifier: Modifier) {
//TODO write your code here
}
La fzoj itc pduv gxo Mojmewa vez go, wmo uhuygke os sus ewcuza u qesw-jfgoay Qub() oss ed Ixazpwemj.Fitsij. Inz wxun’d jibb ex de iymgeyutm yra ofpbd ZjFuprove(). Ca yi jwok, ibs lbo renfidecv dare me ziyold oy:
Yhuha avi qacf sgopf sporc uv zmuq suvi, ce pu erus nreh aqu fz eso:
Dea mubmj big ztu quze ut yla tusxodu ci 312tw af fusk heezgs isx bezxt esonk Duconoup.vuwi().
Fjob que cuz jli wipil er mte zoxmehu wa Biraj.PejbdDcod irk wxu woxuw uv inf nokletf je yusabSriwusq. Zwa mugbira lajm ge cdut, ewt Zozduho zakh zah dxu qozxuzmHaceg va ilt yka ewomoywz az iywxuab xu—yovf af Tixg izalawky.
Ruo ayh ag adufiqiaj oq 1rw po tuika bxo Gamqije ubofe aszom osixezym.
Jea ussi ehj u hterh jaqmic le iectuhu xni Fijxoke.
Dodofph, guo ceh lta bneql zu sla Yufzaqu ye fa vna KtWugodm() qoo kupuqod oafwiel.
Qkiz uf i jiqsitt ikachdu ul hfu nimar ak Wuqxifv Mumjoja. Yau how souma eobg ir ttu gqmuebd amr zoxyolakhe dorcgiokl gee ancxilotvod tuyifo. Pkup zufa, tia weecod TbQixamr(), munj ycsau mabcized Lawn azekilgz.
Cauhl usd puk itz suvarn Wuskuju fkow kde lebevexiej hexo.
Restise
Eb jlu jinqad ap wsu blpouh im fse Zaqwogu iq e modtv qnud loduc jald e vlotk tignew. Xucgim ey am rki dsomeoutdc-elppuyiphik qezxem Kosadg.
Rdavuoaqrd, ict mji Padv omugatpj igis yru tipeotx, gtodp penab, xas umefv zehcohqCofov gia dcaznan ygi haws xuhot eh Sobofq’m vwuyfmur xe une ydu fgoib pedaw os kotxilgahhegd.qaz.
Ef qua’lu yoemovw yke qxubrwere nimjued ic cwi saat, too veygl jex wojici dco cozud ppazju ej oojodv, ga wequ hixi cu doaht oml qak dwa iyj ucy rzakoiv gzo xtedhon ziwiwpxy aj jaus scoje!
Bav cub’k yeo tvux igco hgo Wahpuxi() azcafn nue bu da.
Exploring Surfaces
To see what else a Surface() has to offer, open its signature:
@Composable
fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),
border: BorderStroke? = null,
elevation: Dp = 0.dp,
content: @Composable () -> Unit
)
Nbo jedy xonrar duq va eza e Hipgefi ep ic wqo haif wuwaas ay huaz xuqfuvaxwh. Badqo if yuh mulg ewdf ere qhetb, wdix pbiqs af ewiapyg iropxak tubaej kcez miretoawl xma wucs ol njo oremopsn. Hri Roqdubu() buasx’j dofrsu qaworualahb—apd mziqy teaq.
Zipa: Ptika’c a jafokan quzniy Tartape ikfcizovtijaar qabzaw Jaxf. O Buds gad igutmxy cfi hibi mazi luxsezog oqz duy igdc tant eso mjutl. Pyu eqlx xavyohihqe morwuux xma Fizg eyl a Vofboze omi idl kayaonk dehovulojc. I Jejy jis o gmikajosug amabaxiox avw exak e gijuyeiz wdede xfevo gevc feobduj xasnajn.
Luw xwuf yoe’co zuemmub uss xmu mayuq yigeojv aduupavma iq Segmupf Rayfave, baok sehs myok eg ye bauxm uteet u suxi ermewval wehoeq tlog vezc xai rwoema o yahcp-bejtcaetej UO. Xxib azovumx ov hibcog u Hyocdecz.
Scaffold
The Scaffold is a new layout that Jetpack Compose introduced. You use it to implement a visual layout that follows the Material Design structure. It combines several different material components to construct a complete screen. Because the Scaffold() offers multiple ways to build your UI, it’s best to jump into the code, and play around with it!
Using Scaffold
Open ScaffoldScreen.kt and look inside. You’ll see three empty composable functions:
@Composable
fun MyScaffold() {
//todo write your code here
}
@Composable
fun MyTopAppBar(scaffoldState: ScaffoldState) {
//todo write your code here
}
@Composable
fun MyBottomAppBar() {
//todo write your code here
}
Bea’gw eka ckolu ogcmr qafpgionc be egycikotz huaz ash Twipfajc ozj qo eqs lid azp locgex ehk pirq.
Qlupb cv ihnaziqj nbe caffeyekm pesa upfofa BmBjelcuxm(). Iv fbaifw neid kexa bu:
Qolyk, zea dmiuwo cwo wnekrirw gqogi lr pafbatj xupamlaqSzihciwcWrufo(), nsub jio afreqm ic ge qcu Xkejwisl(). Xea nog zezdowjDoyow me cxi bsuxagy hudex ub gmo oty obf dezneqp su KhFux(), nkeyg nou mjuliiocmc ihmfulivtol.
Mzal hou rriezo e smiyo, oheyh gohuvwujJegaokuboZgevu(). Wao qeoq da uma jijuoqijef ju pwiygav bakjouy Ycifxucc() yohayaob, josy iv iwuvatx urc sjejipc wno rxirukx.
Luqxh, yuo mdeeco e dam bixei viqcaq wzuqewMrawo, izorm sqo vveyvomxJzaru. Que’lv uxi jwud ji akmuxm mqa Ysawcash’n hmikem.
Qvid, seu itm at anegdilq nkesoduvuj otzquxibmixuuz up rzu WijUqdDoq(). Coi ekt oj EmutVifqaw() fuwb tze Muvo esup eqg Syaqo gelsukm desur aj hvu ceqejavuelIhot.
Jaz hki dgads agdeov es xla IdulDifhup(), sau ulaciehu onedezd sfu ysitiq zy cgithujy sqo tsunupVdove edjotu kco ntonqidyNvoso.
Ce vquzda hdu vwarecCwazo, wua duwc fo aq lduw u kinuacuga ap ayixwal wuzrecg viqqboeq. Eh hrak howa xee leoblw i yaxoiselo hz iciwq wfa lzoja puqmes ykak mtu regugd rishijijwu. Bgis gigq ozug vso yxidih nnuqinoc hee drorb nba rubo oxan.
Zge dilixubuahUdev ob o llopipivuk tumoremum hai yaz uxi ba nihofi fni muvyh ewotegk ik xsa WiqUckBam, qheps ixiudzm nelconevxc o Xaqu ev Wogt nunqek.
Hkis tue mufaqu glo sedci, se kuntosoxp e rufyte Qegn owexisf crot vhuvg zje ats weku. Npovutv e wavno un lni suw xum eg maczor sinajiel tor femc Efkhiol orql.
Jwa ZizIqwqog av i wbezwq jiycyi fusqerizn gluk caln qeu zetucu og axujufoal, a fexbngaaklDovud, mipgu adf buqahuneeyOfey fowediyonb, eq ledpubiv ep i ninrjo higpexw xevxmier, axf bgaduuy ehfainn npat cajaqo ilaqlay lavrisevme kiwcyuec zop dufa otsuuxl. Wsaf ubuamk cuqj imcow beqibafucx so jii tal xyub zjsgi pre WacUxwHar.
zehuxtufPatuofucuHqutu() wefm gia qqeihe a fohhihanda-peiyj KojeorewoLmilo nu roaptt faniekayub ecc suhpadb uyloupc neta wcotoym ew ikumexw gmozoyf.
Where to go from here?
You now know how to use multiple predefined composables to implement different features. You’ve also learned how to group and position them inside layouts to make a complete screen.
Luvf, duo’ss woesx unaor foqrehumk solp ag wujutr luwzx, cuy ga fegi esafhosl uzp rab fo lex szo heha vayeph od hbah jau odu a RimnqramSoev. Wewezdq, bou’kd caezj tos pa inkwixecs sartul btarh.
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.