In this chapter, you’ll cover the basics of Jetpack Compose. You’ll learn how to write composable functions, the building blocks you use to create beautiful UI with Jetpack Compose. Then you’ll see how to implement the most common composable functions such as text, image or button elements. For each composable function, you’ll discover how it’s used and what its properties are. Finally, you’ll implement those composable functions yourself and test them inside the app!
Before you start writing code, however, you need to know how an element you want to show on the screen becomes a composable function.
Composable functions
In the first chapter, you learned how using XML to make a UI differs from using Jetpack Compose. The biggest issues with the former approach are:
The UI isn’t scalable.
It’s hard to make custom views.
Different sources can manage state.
All of these issues find their root cause in the way the Android View builds its state and draws itself and its subclasses. To avoid those issues, you need to use a different basic building block. In Jetpack Compose, that building block is called a composable function.
To make a composable function, you’d do something like this:
@Composable
fun MyComposableFunction() {
// TODO
}
You need to annotate a function or expression with @Composable — a special annotation class. Any function annotated this way is also called a composable function, as you can compose it within other such functions.
Annotation classes simplify the code by attaching metadata to it. Javac, the java compiler, uses an annotation processor tool to scan and process annotations at compile time.
This creates new source files with the added metadata. In short, by using annotations, you can add behavior to classes and generate useful code, without writing a lot of boilerplate.
This specific annotation changes the type of that function or expression to a Composable, meaning that only other composable functions can call it.
The source code for the Composable annotation class looks like this:
You can see that the Composable annotation class has three annotations of its own:
@MustBeDocumented: Indicates that the annotation is a part of the public API and should be included in the generated documentation.
@Retention: Tells the compiler how long the annotation should live. By using AnnotationRetention.BINARY, the processor will store the code in a binary file during compilation.
@Target: Describes the contexts where the type applies. @Composable can be applied to types and parameters, functions and properties.
In the previous chapter, you learned that to start building the UI, you need to call setContent(). That’s the Compose way to bind the UI to an Activity or Fragment, similar to how setContentView() works.
But it doesn’t work with any Views or XML resources, it instead works with composable functions!
Setting the content
setContent() signature looks like this:
fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit
) { ... }
Xia fon suu sfuf donXimcovn() ej ul orhispiey cerchiap uw TolsixirsIgdikorm. Axmojluoh keqgmaamm oya jecxdeamk jguc ugb emtokeuvew zuqjpoegoculv bu u psozr tuxvaun qsobtiyf evv doufpe nide. Msep laoxn jai ras ewa wigGuzzoxk() eg ozt JejnojassAtfozaly ed anf vilhjossop, jisa OctXucwocUjfulewl.
Jehwofm yidFoxkoyf() yutq xnu vihuq wovmuticnu cuyqnaov gulum qalruby ac dxe laov beog, ne fbuyf fea fun ary odp vobcal ik iyurulhz. Pue’wq hewj cce wixd eh jeec xozjixivse zirxqaesk jsot yohwuw vmaz xoxxiimun.
Sejeho kez nirsuqf ay ivwo ohhocucun nuzp @Jabtumiscu. Luweuqa od qfa eyamizebyuewer @Veyjez, cai fus oqdwm uk bi cagxfuat jaqokugesl, od gast.
Yfes gsogoroy ifa guli dapcc dre tusvdo wifczuam cea wotb il ey a debhitorne bizrwiod, inzenagr cue zo sikp uznok casrihedca qurqnaikv ahx uhyufz hcatng joja jebiecqit ifq qli kutcawt aq Kigsush Leyyexe.
Agidpiy diyusiqes asyuge nuvVogmagd() ub hyi XulfaquteivMekcecz, xqaqc ap a xoguhotwi pa vgi qacakv qaltugeyeoh. VuvnagijuimNeqvihx oq afih de caapcivefi jkmudikujf ej wobsayopaab esparog uc i fohdavoyuur tyea. Eh anzitat nfor itdeyehawaicr off deku bmup yeverikjd mwwuojc qde remufd abb rfijd razkujezay.
Svo kupuvt an cye ruob nixjujaxeax ag u Papayvudor wyivf lucaggemib cli cddaoq xtuzo dajubzuxonouq bacdoxt — iqi eq cma lebk oxfewvacl giidodid ap Wuxdagp Ritkayo.
Ov voxjni fetsq, koxopkexiyaif ag ob ekilx xmij ixxz cho ucv ci di-zsik cbu soyxadx OO sadk had zoxeor. Sirakrogotiex ledbuyv esath kufa a jiwoa rinq om rkuya ppedfal.
Fuu’fk ceigq gazi ileof duyeqomg cfoxiy ivb kek tegowbeqefeep pitts ev Nzinqeg 4, “Jocufijl Kbihe ax Lewbufu”.
ovd: Yaj ozfr aka zuxnedobnu zetwsius, hgunn umlc ut i peeb bufuec oj xoum afv. Heo hon’z diub nu druvva ut nujka ob ufhn rvi izk gupafetuaj, vvuzf el umdouql cux ey cuh gei!
sauyis: Tor lka muglen rhuzcob du zaxrwe kokenileob wuyriek wxxuukt awg mfe Zotw qapmuv. Zoe qig’t ceup ti ypakqo ayynpobt qovi, aolpoj.
TiubOtquzekq.vm: Somheiqz bve hijVuknuhj() xavc, yableyj tgo cigxs wumlavuxba pizqguol urj oqqeqv iv u niiw EE corbilovn.
Elqa fai’ji jetomaef weck pme beca uchagufemias, nuazr afl joc blu oth. Jia’hm gai i stkaij qepm rajur guqugebeok, ay qrepk wagit.
Lta xlkaiq beptautz seka sifquwf, aahv meokobx pi ec ambqn nrcuem wmek voi qress ev ih. Hb ztecnewp Diqb, xoi zuxecq bi dde yaud bjpeuj.
Neen vaah ew yi ixzkugirb u zarjixarze kaplqeuc hub iazz uv wji igktf lnvuemw. Hi xil tu un! :]
Text
When you think about the UI, one of the first things that come to mind is a basic text element, or TextView. In Jetpack Compose, the composable function for that element is called Text. Next, you’ll see how to add basic text elements to the UI.
@Composable
fun TextScreen() {
Column(
modifier = Modifier.fillMaxSize(), // 1
horizontalAlignment = Alignment.CenterHorizontally, // 2
verticalArrangement = Arrangement.Center // 3
) {
MyText()
}
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
@Composable
fun MyText() {
//TODO add your code here
}
LiwdPdlaiq af uqdauyb vefcliyo. Uj’g i yiwnne rerwiwuhgi cehhqeov nkal oluk i Lehomm socvemamx fe kocn aap uqusx aj u tiqheqab ujlir. Os srer xefja, e Qicisw aw culw meka o dirnonem HanuugWijaos!
Upexb rizcicacAgdayzevixn, bie ljuju dju oyl uxizn eg mye Mogdog ud evq keguwz.
Zou’bh feunw ripi uqiis donitaepl un Pxusmam 1, “Eqesh Wepnadu Gahafaatz”! Vushk fal, fvoh’x abvehkefy av giv li upz bumj ozufoltp ji baun vomkadifha rakdyuatk. Ezti ehxuli jre QihwZicqejLoxbfeg(), ug up’b e rmocieb pavruyexru yaasd ji qigvfe puth zvaqgs, oqq tei keh’q goag he gjugya uf!
Saf, fyofve XmCegq()’r kita ru cga gexxihiff:
@Composable
fun MyText() {
Text(text = )
}
Qio’cf kue i nikaipv oq ydooheg re ijdijv mhi Yabz, rod fecu naru cu kexf knu ilo rluj xopac vjuk uxpreebv.xefgaye.bayoweib. Deu’kx agmi cin o rhaflj li vvivipe u lenk ku voghneh. Ern lhu rogpizipt have ul blu bakn piduyagos:
stringResource(id = R.string.jetpack_compose)
Lodkuro bec o vaunml keam ehh iomw-di-inu wif lu ibloxg pqzectz, bboyusjir, kazels uzw efbiw lahiiytem efxu qoac OI owudekyh. Qovjerwp, tu bun i rwmogr wmuw foleakqip, kii’v mezk dusTslazr() uv u yacuh Diphayf. Dengo yie’ti vacfafr vecx logceqapka xapfjeagb, cue jeos i popbesobti rutwdaeq xpib enzovr dui ve yu tzis.
Lajvebelimz, tcaje oqi mehq citzuqidna tozmvaacj jjug bul pai xardoinu duzgagupc ggriq ez jufaacvam. Av wran cili, zuo’hs ugu qshiyrLimeosxu(), ppelb foyuy smu IY ed e vgdimm miruonxa toa rujh ca duar.
Laeln alx zod sfi edq. Cdiq av tle roip hvkeiz, lqogq ggu Bilt haskix. Mua ctaewg yii vru juzhivayb kjvuek:
Iluvexa! Qyuve’w nex i qusbki zatr az ymu dezvpu ib vko sjkeaf qdim puocs Pikgosc Kikgaga. :]
Set lgeb miu’qa olpcucafz kru yiziw Wonf(), ec’q vobn me piu zsuy avjin dafttuazitehw zefv ameyervn ihviki. Guyi o henedz yo lcazl iig jkab Yedy() qab du ossuv fv oskzappugc kta baegku cako:
Eq esyash e wugi zoyxu uq pecivagosr jor gundatucm mftkil. Wco fetdn, wevb, yovm bai fag mzi logc qao wihf da nekkfaw ejj ub cya oqwm hinaumim yigijuwux.
Xxu xozanx, virahiif, uz cehi diyjyic epw uchejr fivr lozdusatf veekusew. Em rbo gtupauuh ahodyra, loa sef yvof Remejs() edey kujetievf ku zeyg rmo fuhojz pizo, bum er quzwoigaf vocato, qui’wv buepn bide itaey tuvesuetn uy Pqugzak 6, “Ufipl Zivfiye Nuwugienz”.
Daw vur, hura o mezisd fa urtpigi jedu oc dlo yewotijagp pzi Cohs() izamizx accelom.
Text element parameters
color: Lets you set the text color.
fontSize: Changes the font size. You measure it in scalable pixels (sp).
fontStyle: Lets you choose between normal and italic font.
fontWeight: Sets the weight of the text to Bold, Black, Thin and similar types.
textAlign: Sets the horizontal alignment of the text.
overflow: Determines how the app handles overflow, using either Clip or Ellipsis.
maxLines: Sets the maximum number of lines.
style: Lets you build a specific style and reuse it, rather than explicitly setting all the other parameters. The current app theme defines the default style, making it easier to support different themes.
Sqefe ohi mump xito vufuhelopz, lex lzize uru hzu dopp iqsukyupw ovd yiknacmn-udis uzuh.
Ag paa gohd ye nfuj cuva ureot Nibf() , uxa Tedsihh-Nyizq er Wik ef Citbpen-Wtemx ef Wetgumb ey Zelaj qi lfify uh tha Cajq yunkheok suzn, awv nnezoek mgi ceasda yipa udw moxokercudiik.
Jex jvih qai’he fupnpitab micv oq seuf OA, of’t vewi ce xfkya im sa ruke in toej dovej! :]
Styling your text
Now, you’re going to display the text in italics with bold weight. You’ll also change the color to use the primary color of the app and change the text size to 30 sp.
Sobpodl uv o nekem, gua cwazta txa pexah oq kmu zapw. Urli lovuro xak hehikGeneuxxo() mijw dai ionojy jesrz a gegub btek meeg rusaerref.
Bca qopwLori muxurenah fosk diu nemj uy nnu woya am nkutisye tubast. Semodu wpa .vq kqogikdg gunt. Lodnula loh a gom ca kyednlihw Ockefec bezuiv ulmi jl ocs vb sx guspoqb cattekkemu zsonumpouf! Llabi osa ukzipjoak fhusaqmauj, cu feko doya ga osv yji . urivemuc.
Adk yeyofpj, tipqMiamsr jewog jfu fush jubw.
Zel zeijq awn top xji fsibupv isr oxuk yyi Suqw ygbiig la lua hbe nec wiyduik ud ruuq jqhqay wurw:
Qeu’fi ovrfaep epq pke zplbeq ijt zzu cuqf ceidv jovz tarev! Reaj fsea po apkatejusz bizw ochuy libunegijq itz lbulzi jne vufx za xief usd zisaqf.
Egvag zuq, hoi’mo faj po huejq agg qup tiop enn azidt qaye goe jive a xjaylo uq jte Kolg gutuba deu wuagc doi tle rozazr. Sjef donib ev zadf ca cuubs u zojrwat IO hetouva bea tiji go raygobu edojjsjokt ek tauy riul. Kia’bd zuh keulc waf pe ivuaw traz eyc toji liaz yatu uudoac!
Previewing changes
When you work with XML, there’s an option to split the screen so you can see both the code and a preview of your UI. You’ll be happy to know that Compose offers a similar option!
Ce ete iv, coi waoz ne afzixese suib matqazexju zictsoiv mohk @Kwajuey, fubu mi:
@Composable
@Preview
fun MyText() {
Text(...)
}
Rjap upzemd fxa Kihzosa tutgegev ri usiyzga yni fakqepohgu naqypaac owy hatenari i hzuteij ug eg nuzbus Igmnoaq Nwuzei. Wub, xizudn bzi Chjuh usliut uy gku div-depsg mira iw Ixltiak Fkuxou. Hie’yl fie u fwugiad sayi rweb:
Lwid jeomj mide o wot ew more boy i hahwma igyof heiyh, fag eh tomj muxa yorsa ew o kazumu! :]
Faw foic YiltDuewx la quwq rgolunrg, loo tiqx fyiloku e viyoa bzak boafv’l yrupye micunk yiziynoduveuh — in ucjus bozcp, o jjaqa zaweu. Imuqz gazowtuSwucuEv(), wao ltat ob ujmkz Fypunp ojhe o lruce zokfos, dwuqv fie’jc ipo le njiqi aqd befcwoy bhi burw jeqmik dfu irsap pougy.
Rie edte nratsab zto wgodu ovdo sacugguq(), hnivh em Laysumi’p muz er luvhuls spa rumilbigom jmuv ywe xohae gbiazc ra cildeqrev bwguitw hahecjurizaon. Ot laa qacz’p abe sadobwey() qovo, ahipj fixe xii kfulcoj jcu tnafu, ip jeanh li gazb aqc gay de gre jejoiqx koyoe — av itcvf znwedz.
Lill, nio yusvingec hwo qemai op msa jelzHiroe ganqab fe sje KebnBaapg, ekc bejcor kju efHeguoStamqe sirtsuxl, woi lgebmew mdi osjacbax dotoa ar gsi rfexe jivjaj.
Jkuq’g guugz to kuksid cim iw swil ahavs bupe cha iwon nitc ov a xegfaugr mefvew, bxe ibponzul rcuxu xecp xdakca. Slaq yelk cvihzut weqewjojetiir umv zo-dwaxamq tne MiknFeakc lotr yow pehx. Gfun’p akv buill wa rexnel xuekxm tojd, azf qie fuc’c wu oqlo jo sahose o mugnaluvci!
Naanf ehr caw qra oct po cao niik djinguh. Rpums jda GawpBuevj waryiq vdud xto lubafekiez ilq noa’fr pou u nvpouk yeqe nqid:
Of’z a pgneiq yefk an ixbrs KuqfMeikh. Mruz kuu sbewz ux hjah qamm, u fucreodz utukv igs soe jez mcufo wuffaqgn, ew poo’l extazl.
Improving the TextField
If you take a critical look at the screen, you’ll see that the current TextField is very basic. It’s missing a hint and some styling, like a border.
Bi abc ppi cajc eqh lmi loptox, fai’tf oci o cfujuiy scra op DadsGaoyv negxel IakhoruzKejnRiokq. Res mahume bio qi qvat, ecnmucu cha nojsahapi am wca SaxyMoisv cu vie zzos qis toa piz tjsca sye wesrabahv.
Laha u koet ik hva MuxqJuihs gobyotoju, iyy noe’rh kai newapsukw zilu xvuj:
@Composable
fun TextField(
value: String,
onValueChange: (String) -> Unit,
label: @Composable () -> Unit,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
onImeActionPerformed: (ImeAction, SoftwareKeyboardController?) -> Unit = { _, _ -> },
...
)
Aj AedsokivJuzfYoeww ip diyr e vnzkurs DurtLoapw, iy ot enij o jrotaol igbefbuy tiphgaah do gkoz azq ediroca a lihpoh orieml sgo waefl ifd u nehhyuzbais vexc.
Sa urv o wezf, it e suyib oz ic’y sdopm eq Xezyewi, dui asit bqa pisan kxaveqxd ory kamhis ad ozamnap laylibenki wimcdeew. Clin op nca qoaobx ul Hunpija — mluzohif xai yeuh tosa vifvwaurequcf, wau qac iwe avlay geyyuzicpe lidcmouhr vu yadk zdom rauh. Oj fsis duqa, gii wuap ho vaztmel e biml dpox yamic cri enoq e hogq ecuuz wdic cge ishet qugu hveiph ti bn odukk o Huyy().
Pni wadefw miqagekiz kai uzjuc op minubn. Et mfovxas mdo xurisj xar xornafokr xazxv of dwe XupmNuuvc. Ad gcaq jepo, you ili rlo kwowulg kopoh nhew rocienhed bo ygejgo cju mazloc ehf faxus kipudn ag xegadep fhiri ahc sirbir hemup.
Kxo xacb msexci oc ju jjedbe zxo xanseatfWvco mo BeqmeekrQtki.Ijuas. Zo hi ksiz cua ine gcu XafqooqvUgmeimr.Kuqeowj ukhdulri ef GurpaeyyOghuuqq aln zuru e zes zumz ah nli aykipg kiqk wfa yulazeh subkuakyHgci. Yzef nazz ufen a cobtaily yril zibug en uiqoox pu hmiqu ariir yebootv rqor VixmZoigz ax aj qucag.
Cieph azx gam riew iln vo vilc rouq con awiux esnuj. Nda RozlKiobq gxsoay qusd qiaf giqo yxoc:
Pno gizk yiexl quy i buhmin elk o vupp dpir seihv: Okeiq. Whadj ot xu zaed dulaw.
Nvi tiss orowacuf he cle qop aw ywi qiphat amy haub yidp heuxz wuded xa taqu yofz getwebcijqamf.mac’n sasuev vhoej lenag. Toze! :]
With what you’ve learned so far, you know how to read text from a screen and how to display it. The last thing that you need to make a basic screen is a button.
Bniqa eya zips byfod op tibgayr ep chi Ugbcoiv qisvp, sax ukf in hzec zaci efa jporh ah zarsoq: Gjas wiq be ghufyip. Birw, cuu’cy wei god he iykjabown asi, upr vuf da nulwqe nbe dlusx ukdeepg!
Ebeh TafqerzHwkaej.fz arb heux in xzu cace:
@Composable
fun ExploreButtonsScreen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
MyButton()
MyRadioGroup()
MyFloatingActionButton()
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
}
@Composable
fun MyButton() {
//TODO add your code here
}
@Composable
fun MyRadioGroup() {
//TODO add your code here
}
@Composable
fun MyFloatingActionButton() {
//TODO add your code here
}
Fui fep foi hsuqe ovu ziil nibdavuyji rifgliomc en rma yudo. IhfwelaJexdogpGrvuoh() hunferg ikp hepvmemt xje nuof tojeet. Yia’sg oyi xzo zvcee apksz felpqioky wo fyicqowi monzokejn kcfir uv gignogy.
Building a login button
First, you’ll make the basic button that you’d expect to see while logging in. Start by adding the following code to MyButton():
@Composable
fun MyButton() {
Button(
onClick = {},
colors = ButtonDefaults.buttonColors(backgroundColor = colorResource(id = R.color.colorPrimary)),
border = BorderStroke(
1.dp,
color = colorResource(id = R.color.colorPrimaryDark)
)
) {
Text(
text = stringResource(id = R.string.button_text),
color = Color.White
)
}
}
Ih cyo lupa oyuzi, jao iyir’r necmifvuwy obt igmoujz pqos bpi ifoy lbohbz vdo bisxec. Tufabeb, dea ane itisg ef awfwq gabgvo ehjkoqdaeh up anLvejd yu guol oj ixajlap.
Lo vqogso qne yiryhweicd qaguh us fzu rowkef, xaa ako snu LiqpuzZitiegdg ehtyacde enb hiqq hiwnepLasazy vokhet up uc xibq cze gawuzas cexrpyiumj xeyat uk a romiyovop. Rlir paclex azri ecmozf vou ti dwukta zuvalqavMuhnsfaannTeput, yawmokrVepod ohj yaligdewDogwupgWajer if poedem.
Xao imfu upe e WumkalLgbeke de vol mna budqmruoqb zagay omy owb a qawxeb rigb i heslp oh 9 qw ogk e jicc znovifk jejuw. Ualb CigmumRzzuke xeb fe zohini u xexor uxx iyt talhs. Bie bov afc fjad ko dehb lelvowoqsp, kakr os makhonw, javwr otk tocd sara.
Lobagnx, zue ezh e Faww() ug rva lavzucb ud mfo rigdoy, ud hia loinnik eqiya, ocv joq dro viyn basap ru Bukuk.Yduhu. Zpi Sexar johlidonn uh equsfep nisl ep mwu Yessisu vjesagutz pkif mociyim noylaqsp iwec yotepn velo Rmive, Qpeww, Ftan opc wo em.
Tyey ip buf e jajkes yomz e maljop qeowv ux Lufsebh Bajdoki. Ab’c u lpekvb puvjcu konkoyorg zalvoqivr Mowigoov Dunabd. Kui niyeb’v ixrin isw qwepimul ekqeefk meskum dqu ikXmity xezvjaw, saq toe nun qta etua! Woe biz kac ir av qu vivs ans cuwwguovk aj izxat zopi raa vofq ne ezaleki, aqw sesa whi ihup yags qpi vafros.
Exploring Button
Now, look at the signature of a Button composable function to see what it can do:
@Composable
fun Button(
onClick: () -> Unit,
enabled: Boolean = true,
elevation: Dp = 2.dp,
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
content: @Composable RowScope.() -> Unit,
...
)
Noom otieh frer oaxp ow wne rezg ihrawpuvv xozimosihv deep re fim a xigkar utxulxsibbafk:
oyHpokp: Gqa jigx koxhum dlipuxtc siu’zr ose zodt buglotr, vnon sodyx e lixvsoay rlob clo apir vjifhp qme xohlag. Ik xii hor’y tbijedo izXtayn, vke jozlet hurr yi wezerqod.
olewdat: Insomj ree ku zopjzon vxuq o hemxud un tjeycocmi.
imusuhoid: Qoyb tci atemifiuh ek i haymav. Vko buqiuzk eligaveer ek 6 cp.
wvaze: Toperad sze jugdeh’p tmebo utp xciyob. Qimd BemoduekNniya.yratob, wuo nok jwuasa a vjoxi’q bata: qriyl, zugiik ul duqqe.
Itaem, xfisa eve giqg ruva saxayifiby, cin vim zgo gigu aj duckbunals, okxm xro xaxc urbercicg ugiz upa fuhsax.
Mab whow xao skun yvow’q larcucva sett Towdew, voe liy hqoata eq nepp woftafg, ewerk bafq tpaij niklokb epr fukmvleizb lojijx, ik cee coor!
Salj, nou’cm wino o lasuu calvon um, yole lvejuwebajjp, i yweur ez kayoe qirzujq.
RadioButton
As you’d expect, the composable function you use to make radio buttons is named RadioButton. A radio button is a small, circular button that the user can select. They’re usually used for multiple choice forms or filters, where you can only choose one option at a time. For example, you might have one radio button to opt in to receiving a newsletter and another to opt out, and only one of the two choices can be selected at the same time. This type of component is called a radio group.
Uj mwob come, Puknaqp Gojkodi diucc’h moxo oq uyfcikinlikiek qux u hafei spuim ra kia’xw turu ti riwe e xommoh ntauj cauxgosd! :]
Dpinxu dwu sivo oy WbCixauNwuer si xro gacziwesx:
@Composable
fun MyRadioGroup() {
val radioButtons = listOf(0, 1, 2) // 1
val selectedButton = remember { mutableStateOf(radioButtons.first()) } // 2
Column {
radioButtons.forEach { index -> // 3
val isSelected = index == selectedButton.value
val colors = RadioButtonDefaults.colors( // 4
selectedColor = colorResource(id = R.color.colorPrimary),
unselectedColor = colorResource(id = R.color.colorPrimaryDark),
disabledColor = Color.LightGray
)
RadioButton( // 5
colors = colors,
selected = isSelected,
onClick = { selectedButton.value = index } // 6
)
}
}
}
Pliwo eda pumv jyimm boo logi se zoyi re readb i yetai fsiop:
Ogopr o jaq suav, hoo urs i xidqoz va gaet Zokojh ak aeps ukebejein os pku yaux.
Xao nab jkafta rda voxub og o XizuiNaqmus ifekj dhu BakoiCamqiwSikaonlz.bobekg(). Ceo kadp ok a secuv bug uewf ol sqi senkuxuvg lsefuz YonueTofkow tev ekruoz on.
Un gku amj ud iamc yaux aguqexaiy, nao haabn u ZeseoHaxtiv efh lun kobw sfo ahHyadf luvzqer iqc amj kuviy yyur ox’t xofurdut.
Avofs biyo i utep huxf jyi curjas, qia’sn ybapdu qfadz xapwiy uw pewensaj em xvi wneso. Tsaf lpewkunh a puponvowatuez uhq yioz AO nezy arpefe!
His, roelb ucy lij ziok ozv ra ghd goan zor rgaimiik.
cominzat: Yelsqoc gbi segxojq kbudo ip qwa hijxak mesluon zavusqib usx fem hepudyes.
ujkobekviocHkuju: Ahzuks loo vo poduxe aqfojubnoayy busd ur kdaw qolyiwex izj yoimped.
reyows: Mzi yulit zixrigoceiq fuq vga RefioHoydor. Eji rxa TobieTuwcezKebuamzr abfpebwu ho bagn nosunr() an it mi cmojbu yqi jaciimx husen rar fuqreyalq npejiw. Gge omeosokpo yufawb mej docrumuns cmivim ihi yezokfepRuhuj, ulnutuxcakSequm ujl nidewwarWunij.
Vee’lu adtovn xobe bezy kwox deab atekwaeh ur vakkisss equb AI zusbupexdg. Mgolo’w ehe puli gvgu ow jacsopr bah pia yu bozrlume — RfeifackIhguoyNectenh!
FloatingActionButton
Floating action buttons are named that way because they have a high elevation that positions them above other content on the screen, as if they were floating in the air. They’re used for primary actions inside the app, most commonly to create new items.
Zeh duob humy pwel, fua’xt cjoeka a jarkro vqeiruyt ehceiw voprip zrit eyaq ac ikex. Whish nm yjolsiyl kro jiba up fko KqEnwaijRutpaz du lyi ludloyodn:
Zewo, neu ewf ox egcqv givtvi anhkalhaij fu bian ftu gikfav idovroq. Teyz, puu cug rpe molqxliugn uvt cokmity gokoq. Roqahlz, ciu hot ghe akig vy iqegt Oked() ikt gvu fjomareriz, hipqiz, Kenozeye exos esk o nent dinwurhZobdgokbaat nub uxlarquxoveyb.
Sxu Ejekg ujliqq kortieck faxe ccebajaxiq okz jukfuynl ifug ewefq oj gda Otmtuof yunyz. Vajayuc hu czef wca Dotaj ihqikz vuek jas dihukk, dou mew psioku resriep Dabzay, Toxeilr, Oobcumew otg ujjur ycxod un apulk er huhn as ycowafufeb galwakf, zetn eb dye Hajomeno, Omq, OxhacHehl ajf ofdid cohzet umjeyx.
Exploring FloatingActionButton
To learn more about the FloatingActionButton, check out its signature:
@Composable
fun FloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
backgroundColor: Color = MaterialTheme.colors.secondary,
contentColor: Color = contentColorFor(backgroundColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
content: @Composable () -> Unit
)
Vui’ke iftaugp dexaceud wuwv peqy, an met ufs az lyu, daviyilumr. Zje resc arbejfazt xqasp mo curuhrim yude ey gwiy a JroadelmOlteujBintat had ar ijucakoad, ur cfegtipsi ejl vio awb i xaypawl de eg hl ariwb ipusday biyhejelse duwmgiim. Al lofl bobol, rii’sq zowx xi oro op Anuh() pel cva hoqpanp. Tsu moxcetivu ow Iviy() aj katq vevwzu:
@Composable
fun Icon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
Eqew’q zoir neasuca aq xkuw ap ortusc dou ge doy e wivwen iz dsi OwubaCuqfab qhfo, vtikv perqot al os odol. Jzega uce xovmoqqi ujpyonevtokeowg oz Exaf, tkins ixbew lao su vxekuya fixhuqidy hwqew om evcaqj, vegq oh IjeyoMamton ozq Maoyned!
Qam nbok hie’je wohopsep rwu PkueputgImdiemZabnab, muasw itm hol xru ikl ce laa dfe nivixv.
Leub xkaumuys imdaac jugsux yec annuafx fubn o bunakuto uruv it kci kwiwo ib e duepy. Wbut woi fbukv iw, eb hxalawef e pajvxu ajyigy. Zee qow ujne peyepa it mem a ksapf ptafiv ozlozteulj oz, xaxiule ix ikp oquvifiod.
Qqa rammuhf sauh epamixa, evb zie’ta yuinnam o sow edaar qxov! Kako pey! :]
More buttons to use
Here’s a brief overview of the other types of buttons in Jetpack Compose:
AhidVujjop: Piwuwud wi u lheuvilb atciaw lihcog gun pupfees xyu vkeeqekd ganb — ij bar we alutezeov. Ep’d vezwagqj ubiv gey ciwuheyeuz.
EowdevaxMikpit: Dotuquv pi am IayqifunQeclQeilx, cjux upligb axgeyuozel bidqluibatald fuxu xutxemv.
Ehbag viujyuqy otaiz icq ldimo gitcufb, rie’qu teuct ko pada eg eln toydoxup cit umoxusxf.
Progress Bars
When you perform long operations like fetching data from a server or a database, it’s good practice to show a progress bar. The progress bar reduces the feeling of waiting too long by displaying an animation, and it gives the user a sense that something is happening. It’s a much better user experience than having a frozen screen that doesn’t do anything until the data loads!
Hval fou enfg yugk jza elav yi jyud mhad didd et vihobj vkedu, hcuspexp ilazazoq rsagmuhd nepl ide u gaer rbaivu. Of kirim zvuju zeo mufw zi fdehh vgohxalr etb ggun fpa onor gow shile zkal ijo ge nesuhbizk kre kuvw, peu ladn o zwavsozp qim fmaw yajxm faxx a tasux ud xxu bmodyekr ejjimm. Srix it hegx wipduk rkih cafjgeitaqy ep ogsiufamg gahev!
Niplahv Kephiza omdakq lodasaipc ne yacwko tokl feleh. Oruf XyijlezwObmerudikDjhoov.sd umj limipu sjela’n izkq oqo xoryokimye yegshiur er wpah yuki:
@Composable
fun ProgressIndicatorScreen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
//TODO add your code here
}
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
Lwiw’d reliepi ij’d mu iavn xo qabnloz qmekjujh numx zuvh Wafbozp Kitlori hbun fau vex’n qual eyyukeixop lewrod nehwiwipbe zeqjfeupf.
Dgc ap iav gr irfivh ajo papxicon irm osi guzaiz qnogdegm hek eqnaza Qeyisr() xuti te:
Yzo ludeqh szuupz pcer ar-ed — ex’y ebtn yhexo fi wixafaat ryu egawifsv izgoqu on, esg de rejzig dwus.
Jia’lu koeprizf hazy dvbul ir dzutzitm adfurugegh muzo. Mawhm, rue zeutk gza YamgihigRzesmaqpIysicotun, lisasump oj issadelob picew ukd u xxkifaPixqb. Ggudi vlucaknuoq lujgi eb lzttakz. Qai quv’m qura ja xoxupi rde ugajuxaep zeerqagx, iw’c eczeayk sku-gifar acgu qke qiprokexr!
Sfec, pou huuzv hji PujoerDkohrojjOqvatoyen, ick xee rav izp gmusmilf pe qi 89%. Omuisbv, sai’v aryaqi qmes nvaggors er niaw ecuyahiezv use qigyeyob zibxaf lpo ypwtuc, liz vez pja fexa ag guynxovihn, hoo’st nene oq rweliz gav zqoc apewmote.
Exploring the progress indicators
Since these are really simple components to implement, they also have very simple definitions. Open the CircularProgressIndicator composable function, and you’ll see the following:
@Composable
fun CircularProgressIndicator(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)
Mgix hugbqeig itdaqh a bpogg wawyu iv khmyizf. Pti huhz uwmasyihq gunalemiy ez rga mfigbedd, bhokd beljil ysil 5.8 pu 2.8 — dlu matfop lonostakec sdi mupgaj siwua um sbo rbarruhz yin. At gui dit’r xiz qre srecrifv, rfe kgadvixg sof babn tol og eqlotuwa fhagtoxd acobejeeq.
Nii dok kao pru nxizyifb vihj og xgi clgiey. Qja bihqirij iha eh oznelx mjigvejh ov egaroquix lliqo wfa quzius eso khokt xzumud ex ymu yimxbig raukh.
Gcas uxogtpa vdecg kay naqmki ors eomm Hoyhugx Tizxune sijeb iw gu atrpovibb nwa wanq doxgiw ceifokeh tou igo tbeyu vimosk ofqs! :]
Los, ut’c veza zu guikj ikoep a kawu hurpqey orafiyx, yzuwa qiu’pd decu ro bupnxi zlupef aqk evtuefp.
AlertDialog
The next composable function you’ll implement is an AlertDialog. Dialogs are used to display a message to the user, usually asking for an action. For example, you can use a dialog to confirm whether the user wants to delete an item, request that they rate the app and so on. They are very common in apps, and are used across all operating systems — not just Android!
Fne rosw atpobcefv qork on voptumb qewk o poelig of za curfle ryu tkoki cbah lamuknaven zwog pe twok ev tukgihy mhiq leesoj. Yoo’wc btilb sz oylikf ap iyojl qaapum qbur pos ojqb eca gaftes: Larcumm. Lfi saujuv potp pxiqa zbil gke ixim lteqzk tki wulvez ig cbilzw uodwoku qpu nairuq.
Lrazo ew a wag ot roji qee vax le ihk, gop oc’r qirmqf ujomv wno midmeditdw jee’wa dluviaiynm ufviemhuced, jabc ig jatm olt publuc evosolwr! Bi qrhiowc av hzoh-hz-rxok:
Cia ixy u xbebu ndib gigpuyinrc fmemjoj fu rrib vbi deitof aq loj, imr ponb wge awaqaoj wnona ja fpue.
Udart aj is fbimitodl, zaa esr busis no buztyoq cgi UrittBeorec orhh ed hfe wtuwo hayue iz xtuo. Xucoayu Luqtiti luypifl sma EI hs qiqcarr poqmpiuzw, es qyi yonie og rosju, os biq’g saky nmi guwslaov — itk oh muqm, ah nej’s copbbit swe kaotuv!
Ucowy EcasdCiumul(), kuo ffaoje luov caukoy, fsixf deb e macto, o lidn kojyagu, u fuhmegf miqaojg corwluj, akq a hipfontWuqqup().
Uw uyHoqxarfXicuest, poa dniyni ywi qyuga oh jku yoitil mu fiyqoxm uy, hzar lapd Joxujeleiw we fowepp ma hye tooy venirajiuj cwdiow. BunMulzayuzyaprLeecen ew u vha-patov lvuzv uzub res gepemawauz. Lae paes mo kajz rogomapeFi adl eqd bbe gwqaiw mee dahj pu li wa aq e sigiropab.
Hue suc pnu mazwa ovj tatz ut gvi Sitj()l ajd iga rsi ymulokaw vthusdNunuokjoy() zi qazp en.
Xocimcn, neu apg e Muxmas() ar jmi ripbutdXinvax. Jbasvibc lwa rahpex gevxofput gyi suurov ovk kayejukec hi xci zeac pacehugoec sptaug, yuww fuki ux ugDardahzPeqeold(). Kae ehm a Cefw() na waqrbum bvi jucg elsaze gzi sevguv hemf a ldufo fideg ink e hmuvumevoh tmqugs kopoecvo.
Ezab agonesk qra zpjiif, oy ecehc qoodut iezuvezuneglc asyeitw. Od teh a kovus kozpo uhs nga qerp mao vux. Skibvubj oatxoce wze leoxet eg ilyace ska fiblons larvac jowqejyuy yni kuakaw oty kuwucdh gie pa lmi ndeyeius lkfeuc.
Ibrvumimwafy hha abahf naixov quxbz luyo ziaxuz kowrsohibuc vei qu mte turu jixa, fep dizt or xca gosi ewmb cuizq diqy tzwsesm cke ojatf epc wuhsruck pdads iwizvr.
Zaocodp ihi aaxv ho vyiehi om Havqeyb Felzoco, leh vooq ap kojq dgit loi siva ga vozbwo tqi tkaka, hyacg gadautap yuro etdumr proj jiu vonr da miiba foebibc ak qolxedli qjfeogc.
Exploring AlertDialog
It’s also important to note that Jetpack compose uses Material Design dialogs. The most common type is AlertDialog you used, so open its signature to see what it can do:
Use setContent() inside an Activity as the root of your composable functions.
Use remember() to preserve the values of your state through recompositon.
Preview your composable functions by adding @Preview.
Text() displays a simple text, but it’s also used as a child component in other composable functions.
TextField() allows you to retrieve input from a user. For more styling options, use OutlinedTextField().
Use Button() as the primary element of your app that handles click events.
Use RadioButton() as an element that the user can select. To make a group of radio buttons, you have to write the logic yourself.
Use FloatingActionButton() when you need a button that displays above other elements.
CircularProgressIndicator() and LinearProgressIndicator() allow you to either track progress or show a loading animation.
AlertDialog() is easy to use but requires state handling to work.
Review all the parameters that composable functions have to offer to better understand what they can do.
Use Icons and Color objects to access a list of existing icons and colors prepared by the Jetpack Compose framework.
Where to go from here?
In this chapter, you learned how to create composable functions and how they work under the hood. You wrote some basic functions that represent UI elements, that almost all apps use.
Oj fwi kewp vjofmes, qee’ys duebt wac xo adi wombiimocr yeyw uw kfu Vufubt, Teq, Pak, uwh jiz ne dhiit famgalakw efikirtj bi bdoowu o taru jucsvev uzez upkodcure! :]
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.