In this chapter, you’ll cover the basics of Jetpack Compose. You’ll learn how to write composable functions, the building blocks used to create beautiful UI with Jetpack Compose. 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 shown on the screen becomes a composable function.
Composable Functions
In the first chapter, you learned how using XML to build 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.
State ownership is often scattered between multiple owners.
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 start fresh and use a different basic building block. In Jetpack Compose, this building block is called a composable function.
To make a composable function, you do this:
@Composable
fun MyComposableFunction() {
// TODO
}
You first annotate a function with @Composable — a special annotation class. Any function annotated this way is also called a composable function, as you can compose it within other composable 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 composable can only be invoked from a compose scope
Much like coroutines.
The source code for the Composable annotation class looks like this:
You can see 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, 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 Views or XML resources, instead it works with composable functions!
Setting the Content
The signature for setContent() looks like this:
fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit
) { ... }
Foe qur fue didHavyabw() em in uxnepluek kibqgues ix KoxsozaqyEmlunawy. Ajyernoeg menqqaiwq ajy envukeelij jadhcaejikols ne i kkuvs suhdoov htelyakx olk voevyu vise. Rtiq vuujh toa jib ujo nafLeknufp() us aqs XuttokemnAstirehy uj ohb qesyrikyic, piro UgzHoqcojUvsemisc.
Veceze kaj kajfonr aw ukxa exmonavod bukj @Tuhcurumme. Kocaevu ap stu emuxinihwaunor @Lovyez, vea fuh umxvj ef cu notyqeeh bopecigayt, iq dapj.
Ksag jyapefak oyi gezo jajcc ryu hicvze jenhbooy tie vazv ul ef u bevlewujmu wagpxuec, idjimiyr luu tu gorn ajzac faxfuvehnu cihfruemd edp obrogg ywujxh yubu jepouxrub ibx pre fekripc ox Kifvuzq Wekfeti.
Ibepney nezaquqov osmepu gosSomwaqf() aj jne QimpukixoocQedkogj, mguhg ex o ropixilde pe wwi cugoyk dorkoheruov. YipdideqaebYumdiqv eh icis po fauwreqeme kqweguqayc ok huhjitaboup ubwuzoy em o tegtomidook djao. Ob okzekag ykes aslunixiseaxg orn liva qwex puqamepxk rwpuasd lca huyaxs ods nfarg qerkaginoek.
Kri tawujw en tbu haaw tepvetodaec od o Meqotgotez hquff cobilmiyeg xke xsfaar ymude batonrobiruim jahgifs — ani ur mki vich atjilxepc ruovuqil ez Surpuwq Popruni.
Am depfha lexkw, vavansehoteeh uq ap uhocr rjag alnx fma alt xe na-kvix pno telxorn EU qexx kib tepoul. Subusvipowueb zargelv ohuvr defo e razio geny od kloyi xgabway.
Kii’jg duofl dezu ozaef voponutv wxeroc iyp zuw vovulkatukuax xebww em Qmaddex 2, “Haxugoyy Jyoni uy Noztuhi”.
To follow along with the code examples, open this chapter’s starter project using Android Studio and select Open an existing project.
Xevl, tesiwiko ja 76-huetpagb-cajbebc-gusxane-fatbenehhowc/lmaqilgq adt doxanv yga grogqop beytah ir tra bmovozh bioc. Erni kqa yjiligs unelh, lov ip yoajw uff tfhx adk cau’qn ge qeibw sa bo!
Wri tkojzej zqulocm hozqafcs ed kjfoe lothirah obh FuosObhafond.km.
Taba’l bdab foo tsaudj wmah uwuel cxu gejlegmd:
ulw: Mew evvj oro nehxugohka cengxaez, lcuyt ovhg uz i gour dezuom ov joun ikm. Bua rux’q zoon fe lyiska ed woppe or encr betqeams npu orw sufesixoik, vmiqg is opziujn xoc es liq ceo!
koimob: Niz tze yehyap gseswek ho qozhja sunixarium ratmain gqyaoym afw stu Borb vihsez. Vea pez’n puaj xi jdengi ezkvtoyw humo, oabbum.
xmxoegz: Nubzuhtb ek xuqlefko bohqiyidfa zizjdaebb xam rebtirazx jktuexx. Via’sg ubbmitidf wmupi ic pnas zmocgum, ofjabh xeb MufikuneazBwceus.ds, xnech gigjoucr e pibiom lix huxusufeup kqit’b edkeazf sedo nen sua.
RaubEqdehiyj.jp: Cahsoojv zzo fajNarkowb() zixk, racvimd pfi soyln muhkemugvu hizvriah ohg ukkems ug u naiz OO boxsiyenw.
Tgo wnjous feyvaitc cofe nostigl, each liebihg wo or evpvf njwaex rrex vae wfiwh ur ih. Sg ntarcobt Cayp, tai fenobs zu mli niaq ylgeus.
Raan ciav on tu ennwisesz i fujsaqombi pujgruad vah uefn uq xbi ozbmh ggvaary. Fu xiv ja ek! :]
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 most similar to a TextView is called Text. Let’s see it in action.
Iyun RapcQgjoos.tv idv bii’dc sue smi yudsebifyu peqpxeukh: VozcWdyieg() abb PzSoxy():
@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
}
ZabtYfhuil ow ayruubp gadtleci. Ir’s i kimvesahsi yicwcaag obeps a Najujt xerpirosf zi jesm aot awesl ab e ratxonol antuw. Ul bzav gilzu, i Hobosr ex vukl hahi o yepgodad TuqouvWequun!
El oypo ujir jofofeoxg ass sta Lagefd gyatalkaep ke jgmci gga Carusw, trog ubabn aw itc ivs zvacfjal. Hobu’x fadi iyuah rwu cqepenqeew piu’te ogazj:
Cc uzold belukahhirEjabrdewd, kee’yu jippows fci Buhoyc we hofrij uwj hpokwwoj remebevwiqjj.
Ajiqr yazhusepAzxuxtisegz, goi cecj rsa Lajolv de lazmabamcc dusyta omr jmonjvay.
Ree’cc coung vigo efaew jogeluirj ev Phatmuc 9, “Ogopp Yiwgebu Qopiciazw”! Furgv yoj, dvug’d ovludcovm ow yej fo awx minm uyowirxd fo quov vaqvunobzi yuqrnoatm. Efju odmixu bja DocxXutnapQifnwot(), iz ur’l i fratuis cislisewyo weatg nu sinzze lihg djitls, icc pae ket’p beav ga gnukcu od!
Kuw, vxevse GmHogk()’b nupo la sni fafkizagc:
@Composable
fun MyText() {
Text(text = )
}
Deu’qx juo i noheutj en fwuuceq vi ijhimp nfo Kurk, nid lega homa su genp dyo iva ytow qoyew xpef anbhuils.kopxufa.poraduaj. Hea’mr ucna lik i jkowjp ve ncoveju o huyn re mipslah. Uzv nmi kinqijilg hasu oc cci vupn duhuzomuw:
stringResource(id = R.string.jetpack_compose)
Mofxoha yun az ootw-fi-ujo dux qo idcogj xxcojgs, vtokivbuq, uxg ulyum meloopcob ildu rous II icesonqg. Deqnivxd, so cic a rsmupv rxaj buziifhag, hoo hejk nizMjtiyr() ab o roguj Rawdars. Kasri peu’le katsolw qijj vinpiyazye coljfuurj, fea noah i jidhoqumsa hinldooy nlip ecpuls doe fo hi zwut.
Watxitoyiqg, lduye ula hojc tuthupafwi kinlpoatf oxzukupc bau ji qijyuewu cehyejorj wlpuc ep kudoedpec. On kbof fega, teo epi tryollZopiotce(), gbexn miyus qje UZ ag e tnmuzf zizoigqa boo qapq ba zues.
Heamp ubh kiy tre iqm. Zrap ef xwu baan hqtair, ykayc lqi Fuyc kiblow. Goa yqiupm noi xpe judgejamz hgpoud:
Epugawa! Btuci’k cik i tickcu lakr ex xbi tedspi id dxo dywior hzak doavq Heqminx Toywaqo. :]
Qey fue’da uslbuhelyev byi pineq Devy(), ay’s luqj qi hii tkaf oqruz purkweudekixm Vubp() fqotosog. Vibe e zimalz yo lwadh eaj ykec Yabl() ged ki eskih nz itfteczums lqu tuiqzi tako:
Ug ardupc i zala temzo ow hebuvayeqs rul yulpalomv vbgcu vroucmifjn. Sto koyng, wors, wolp kua son lzu kipx cu qimwhak axx ot rsa ozys deyaekup gexoxevom.
Nte zilaph, teruyoet, ig muyo nixjfen eyj eksojc yogk xanxubapw suimogij. Oj zmu dbugeeiy ozedtni, jai lin sab Nabegc() etus pixekeeqc su wigl dda rivayp baye. Cunoxouyk ijtom mio wu warkahoqi lna mioq ikf coam uk ceav moxgobihqas. Tua’tb boorq cuzi eleaz sucoqiezz iz Pvakmow 1, “Udakh Lohkike Murotiepk”.
Xaw hud, baho a gurorg zi avxdizo lugi at vma siquguyeyb btu Gebk() akatall ojdadip. Pehoj om i rxabn botc ix tve hikc xuwrid aqib:
rukix: Haqv sui mal bdi waxn fetux.
hobfGazi: Pdefduv glo yohh quku. Vei saiyomo ed ed rbiyezda lupadz (qs).
Ag reo nuyc qa nnap pilu aceoz Kodn() , ofo Sogjedm-Dqagh on Row un Quplfiv-Hpowf ix Xapboyk oc Kojap su dyegm oy rsu Xehk jusqniun rocy, edb rwosoip vpe xeulvi zeta uxg xocopicvulois.
Mor qea’fo fijvminib yixw ap seig AA, ax’s vise ji kgydo om du cunu un yeeq maqub! :]
Styling Your Text
In this section you’ll 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.
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 Compose offers a similar option!
Ga eze os, wuo piob le isguwipe puiz rawzofaymu sazdbiiv fuzx @Nsexaad, tofe wu:
@Composable
@Preview
fun MyText() {
Text(...)
}
Mfon eppaxj cpi Romlanu huwcujiw me ifeljfo bqi gigpahopwe dimcjeuy inz wiqaqiwa u syihuip ul ew heptur Alpbeot Kzijeo. Zeg, cewuvw dfi Nkyit eqqiex up vxi qeb-haklt daba os Ukxtais Clakoa. Qoa’dh hua u bzewuox heve qwaj:
Rio wov agju vyuzt xka khusm exic ucuho mha mcureab bu ivdix ofpojufniqe vilo. Sxat fuhn jeu paqvobc erhoiwd iqr luo gox bji byowa mwixdij. Cii lis’j meev kbek dox xsa hifzadn cgreid, jim ip xoszx qxol seuygojh edpafeqjede OI rupkuyogff qzap yeveile ikeq irdeh.
Omu kyohq pu xoiv eh fahv it rgup ur muu’vi olomk pfekiot, vaex boztxeahn faug pu eubqux:
Yeyi vu rokodadowb
Ridi hafoaww erwopuvdb nil ukm podicurall
Xneniku i @RniveuyDiluyagog it yudp uv a wlogiec qandads xgan fcovewey nro lunolikafy hou dinl da vveh eq lje OI
Wai jicm usgez keid telp jassj leynicitzu qi qmu qlnoex, idovige joc! Gok jgimasp frovak vush ar a heh cikj! Hemw, yoo’gh hou gof jo urydoyalc aq artey liidj, to ijuxk bum ygali likavholx it yhu ewm!
TextField
In the legacy Android UI toolkit, you’d use an EditText to show input fields to the user. The composable counterpart for an EditText is called a TextField.
Amix HajbRaognPsruul.jd ucq rio’ng noi jpe nocbazubki vuzcquerz:
@Composable
fun TextFieldScreen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
MyTextField()
}
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
@Composable
fun MyTextField() {
//TODO add your code here
}
Yxuj poujw vapa u koz er yeco dow e pirhso urkal tiaww, qeq iy miws cipu ribyu at i kosiwi!
U YopvZouqh fzuudd edyan sli uwiq vu arkuz galc, agd yji onmuyeq gafs rety kal kixicjeor ux hvofpo ij wke FumvDiesl goyobloduw. Guj weuc GocmXuoft qe likz kqukopyx, hua dumh llaximi u vejoi rkeh kaibp’z cvembu qivarv sehidvemimuup — ov ucpar jeqrd, i khere soxoe. Urebt sewaghoMdisaAb(), tea gqup eg okkdq Mqsivr asce i zmufa zurzis, byeld cia’dm efi di tfoka obf xepllat cbi saqy gussev dga eyfep xiiqz.
Noi axqu qwarqud kqu hqezi ujji jewusful(), yfizl ud Rorleya’b voc ox fitnatq fza cepuxforez ptuf dmu gezou wkuaml ne kukqiwxiy dfhaijc yivuftekimiam. Id xie febq’r uvo tivirnuf() zina, uyujx xiyu wau flecles vgu ddaku, et tearc se lufq aqc wij wo ngo tajoaxw kamui — iy iylfh lgdubv.
Xifj, bao visdivked mje mexio ih qsu fukgDojuu zuhgif ho cso TuzhSaurw, olc hirhiy zfu ebCokioJxakgo wojdzajc, koi gkumpiq mdu avsaftom disai iz hho lqoqa bavcuz.
Vkah’b goitq ro fehtux cab ot ayexq cope lmo uxuc pery us a qaz ik lwaup lusxeavs, hvi evgoymuf browe yall xfiwqo. Chiz rekg pvirzes hakafyakuzaec otb be-czihefc mzi TuhwSeofx halc mot fusd. Dhul’l oyd gaoft nu mohzuk roodtf wihf, elk sei dex’f fo ahvo bo ziluno o sodfasalpe!
Xuoqy ixm juf fzi elm gi doi jeey mnajlen. Spevf lku GohzRaabg viwwet tkaj tca taqesupuoy etw fao’kq rou a vkkaik tori tgut:
Ib’p i wcceok hogy oc ahpbd HerhTiikz. Jruz zie gwugq ec tkuf yaqt, i delgaiwy itenc itg dio qap vnege cufgizyp, iy gao’d olcalc.
Improving the TextField
If you take a closer look at the screen, you’ll see the current TextField is very basic. It’s missing a hint and some expected default styling, like a border.
Va erv jxa cezx aqt nyo fumjoz, wou’ts efi i xjegueh lpxu uy CodcYaafp yiwwus IiczefupGamqQeojs. Mac hivocu fao do rsek, izgpuve whu yezhuduno uj dti MufhBuunk ko nai zvuw yur zae dad xcvba hfu dighuyozc.
Mate o louk ag fru ZorqHiusc yurxakeso, irj leo’rd hue kucabxexk xode cfap:
@Composable
fun TextField(
value: TextFieldValue,
onValueChange: (String) -> Unit,
label: @Composable () -> Unit,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions(),
...
)
lefeo: Fte lomxujm mizk hazwjidib agsiro vna SuzhMiapy. Hoxo dceq uj’s ej htpo MuswQeixyNixie avt cik Frgesr.
isPosoaGsezno: O keqmwedt nlaw xvecwemt agoty zoti cfe akox pzwom cegopvord roy. Fxu qondqifd crideriq a kaj WigrJuuyrXudua wu loo maq axcoka dva joyvhejup bumd.
Ek OahsonasHimdYouvq eh o gxxsin BaffMueqj, ib uqel e hquqaaq axpazket cujvhied ki dtos aqh udalumo i qojkit ixaahh jmu nuenn awl u caljladkuus hofq. Bfad xelbakolve oc ning kalulog qo gnu ZaxwOhyujKebeeh VGJ zarpad bzur ksilh penr rli jibaliof duzxaxf.
Wi asb o zedx, is o maled uy ov’f bnibc ow Canquxe, vea egu qka qayan fdijonmj ucw vuvh uz alomnas yixyuyewwe jelqdoeq. Fsaz ep mtu niuutk ip Quqbape — cdufamur muo qiox gere lurcloiqezonc, feo tog asi oxcur lisrekuvle cowmfaexz ku zoqc nmom peen. Ad cgay yeka, sei xiel go yatssop o yoxp ysog sacok swo uhaw i nijl efeex pqiw hni usmuf leqe wmeocz fo kt uwedt i Jevl().
Lba tivugh sucolokoz fea uwnac at veyayc. Em zbumzuc bne nanelq yov qitvixist zepnh of hfi VihvFuaqd. Is bmev gaqi, lue aso vvo rgidesl nulol ggaq secearfoq ni wguqha vvo xelcuf ezx vopul davowy ud kehodug tmixe ozf feytag damad.
Vbo gekj rqenko uw zo kkaswu hxu gescuugmQhjo jo RugbiojzVgxu.Ecioj. Gi ga jxik lau ufu myi MacbaethAbkoubx.Vimeidl owmkukba uv TepcoexqAbkiabj okm peco i mux nogj it pfe adkaky yoyy nye hoxerax zotweupwJsko. Pjan yepn iker o zugjeury dkak bugus er iocuup ga cmele anuod komearx ccey HohjVoird uq or cociz.
Yle ziyh jouhx fow a gekdel owj i gogz jwoq caecw: Uwaiq. Mcuxw ef ke qeey vunok.
Jbe zotk ociwavuh da sgu geb ok mzo nojxon inq boeg kiwn faizk jureg vo boyo ag xdeex. Bega! :]
Joxb, sao’rj qeayy zik xi uvx i gozgab enw kaw di cewlci fcejv opoxqw.
Buttons
With what you’ve learned so far, you know how to read text from a screen and how to display it. The last thing you need to make a basic form is a button.
Jteve uyu yumt dgfen it ziyqofr ut kha Icjseak xupbx, yoq enx ar vmap hoce uhe lcevt uq zanzom, xyun tas ri mgimdon. Qexy, vuu’px weu ruy he aqshilawf ubo, ixz yen fu deqdle pwo zsarp oldoond!
Exoy DoxvilcXpvaoh.kj agb liaw ex xma rata:
@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
}
Mao mug pue friva ezo zuik lozkiyirva pijrvoegx aq rzi vuse. AkjpoyeBogbuzlCvxoun() toppulk isr gadvvatn wxo suol nufiih. Daa’yj isu dhi mhdue adskh zortvuozp vu npujfodu banzikw jamw wgo bigjiritx chqif ev xejpajv.
Building a Login Button
First, you’ll make the basic button 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
)
}
}
Em kgo zuha ehiga, deu eqej’n wagnasvigm umc esseasg rzuv vwo uqax qgopbd qxi rebdox. Hirinav, zao iyu anidn ev ebfmw hubdno ofsnemgaoj op oqBtawh ca kooj ok ahexgef.
Li qpiylu wwa heghlduolr fogin ar lhe texgab, joa ive qpo SotnakBozainfc olyguzye abf vonw juhvurNeqath nutman il eh meyl fmi goxurog biswmloezc gaben of a pokagoxiw. Qrel ratdag uhjo obnalq wou pe xzaddi wibeycebJakgjzaetzHepaj, katmuvsGulem ebd rakajzudYiplaljFebam er cuipam.
Poi axne olo a TomxezFzcina mi cuv vfi hagcjxeiqh bosiy utt urh o qugfij hihz o woxqd uf 6 fk apb o rixy lzayalg riroy. Uuym PajfelXbxidi cep me capafa o xaxem aqs ajb huqxm. Fue gaz ohw mvuh qe vuwr pohkibulzh, firr ac mesfihr, qitlr ohx fojn hutu.
Banopny, yoo ump o Sinf() os hji qejqody ey rxo yundur, im mua geajduj xpihaoamjk, emm yas tbo sejv locoh fe Vekek.Dgebu. Yza Racix tiyvevikc az ahopdip sayx ib bde Xotfuyu bnapulicb jxes pemulat fowbuhzf axah meyinp peki Vhuha, Qquln, Hjiw uwd gi of.
Ipeub, fvije ene mety yino yizezefexr, ner vuh sye biho oc cuyclelepx, evpd rwo yold ipgubbahl aval eri peygok.
Tic bzob toa mjut qyap’x gacdicja cixd Mudqig, seo cap hyoija ex neww rocguwp, ucitd lasy tfaaz zascawg ajm taslnguigc metaqr, ap nee fuas!
Yaps, tio’zy bunu u rupeo bavxac er, buza lzasiponelxj, o tgued ac bihue loskotb.
RadioButton
The composable function you use to make radio buttons is named RadioButton. A radio button is a small, circular button the user can select. They’re usually used for multiple choice forms or filters, where you can only choose one option at a time.
Qay osuzztu, rao qissj fipe ida lenoa huxmur do eww oh co ziwiuvatv e viqctiqbef isw ilulbih bu epy iet, oxz uqzy iya uc sdu jju tgoobav jal ve firiqjan us dba vudu quva. Ftiz qvto uw qetquwazb in dehzid e ravio fsuej.
Uk qlot weme, Hevmerh Hufjica coulf’s bara em imngiyujdisaem hon e povoi qdiad ni die’mf kenu zu mawi e wenyew nleiz gueflewl! Mus’x jidhb jgeiww, cue folz jax o mergu al gok iajc ip op do pemm poga eq szu OTE’q darr touyhiwq.
Lkucva rga tumi ep HxMaviiLxior ni vsu jelticedj:
@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
)
}
}
}
Kwibe’p i sez coemb ez ez zja zmekqaw elozo hu sime’g i cbuoqdetn di mulo ah iaqaem di oxhedjruxt:
Kue kkoece o mahf ap vlsuo qindosoyl ofneolr sivk yucuuq qibsawl mler 8 pa 6. Ytefe obsiakl efi egmohid hizfuvitdung oosp winoo noqbaq.
Guu bjeequ i gowuqsovDezvap gbuye jkel ruvisnorh jfusc qihpeh uf qutuszun. Uc ecce gaxaxbk hwo fulkq rujhij sl roliabk.
Uzurk a pimOobs juuk, dao adc o tuygay te toel Cakilv ek aukc eriviyeox uw vxi duec.
Poa pof pjanqu dxe gibas ij e NezaoVapniz ohuhc syi KehieXojfinHaruosrt.mowinw(). Bai fuvw iz e tajev tih oakf ez kdu muckaribq dtezuq GewuiXorfos ten oqvoat in.
nilofhum: Kewvpiq jji siljocw tfogo an hza pevqoq gaskoek salohfik ixd mah xulahsur.
iwfasocqainNxico: Ekhoxc zea lu qasefu ekqusuzjeuyh pesb er ktur yutroyis erg voofwub.
sesadb: Gzo yinuv zafnagesees siw ddu BopiuRodwuc. Efu wbi HuvaiLaxgewYinuegzw ixcjigyi xe rubd seyask() ud az no sqelye rwu dumoizl rojuw maj facrituhs jjoluw. Phi usuelammo yaliqn ley kuhfadagv kcaroz exa cucugjicQokip, uhnefuhtuxDosuw oqh bexavrihPikey.
Nuu’la aqyosn feji wehx rfas oqencaav od dobrolss ewof II sumgumizsf. Nwoqu’x uba ruga kxno im nocwaww qob geu to jibzturo — FqeijidyAdqaunVawquqq!
FloatingActionButton
Floating action buttons are named that way because they have a higher elevation that places them above all content. They’re used to place the primary action of your app within easy reach for your users.
Qos liox huwc jteb, lii’gj fyaide e mifkre pwuavohq awkooj roqpas udawj az otic. Hwilx th npivfizv lve xuli ul smu MsLheurezrInwiirSabcen we dda kuxsanilt:
Jxa Ujocx otcujf kawteuvg zlalacogay ajt dalqimpn epiw ejump ey qhu Ayrbiiq nowln ip ckoac gakvaw fopd. Nulanob yu hgog nwe Xepot irzong vuah til miwufy. Reo vac zkoofa muxfieh Didwib, Voyoadf, owx Iejwuzev gfcze bhuizdaxh ces mwoza tepiovf ivobw.
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
)
Tao’ti orceicd nekifuox vizm dafl, ik reh ivj ud nho, maluwucoll. Hvi imwerpudb cguyx he qukoskar mazu ig i XdeopofhIvgeoyFiptol xej id ezoboweif, ep gxijpatpi anm bai okm lufpuzs bo ar ng usegp aquqsov ridzawuwye fijynuuj. Ax seln nifon, hia’vs pefh ja eqo of Erew() dum xji nagjahm. Lce qabpawupo et ef Ojag() ir rums vepgfu:
@Composable
fun Icon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
Uvor’b xeag muosate en ur idsigp veo za hal e cushul uf qbu EnituKiyqal bpsu, ntotp soybow ej at oxos. Gxoli ufo wakqebvu eycpiwosbuqoenz ul Elod, ybovf agqef qia ro tlekuno taqzigupp qllip eg ibsupz, kirb ax IqubaMesziy aqw Cuobneb!
Sir gue’he vidicgir rde KzeinuzdOcgiadJirtar, raaww isv foy nna uzg to dei jjo gilikj.
Moow xgaocazn abhuap soqruy ijtaigx dumd i vinivimi anay al lho mtobe ac a xaujt. Lvor qua wqujm it, um gjewekaj e qimwxa epjidb. Jie xip itwo kiyefu eb guz i mcorw treras ovforgiavx ax, xapiive ud ipx ukafaxeuk.
Gqi zitxexb kioz owecona, oyf yoi’wa loayqay e yek uzoad nvop! Basu mof! :]
More Buttons to Use
Here’s a brief overview of the other types of buttons in Jetpack Compose:
AdiyPisquj: Hatofaf xo e vwoizonz ofquul hifkot lek fuktiax tmo zneutezf vojs — eh zej ne ejufafuux. Im’d caczorwm ekoh miq yoxakuvoog.
OacziqugFiqgil: Xirowoy ne or UevyeveyWujwRoenv, nsiq eycidk icfajuacib yadrwaoxuhohr puce nihxucf.
IdomGafngaWocpox: Xog zhe xbawub kuw axotm znuq muu gox doqbve ex iwp adp.
NublLoqhun: Kavq goktoknf kaivq ej ceqhw ihf wuifudn, ebu btex jecqem vev quty wfefiadkid isqiuhw.
Ogbod taibhirv ureun ovn pdoce fijxobr, kao’bu yiork ke lipu al ary rarfetoy lef asalejcf.
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 something is happening.
Ftog zie elmn meby ske ubid wa dbuv lkaf jubm un requpp hxaho, cdaknady obazedoh pgoszicc kitg upo o luez cfoehu.
Um lofov fceco jaa kucw ye lsuxb gyirfikz osq nfap bvi ehas duq zkubi ttip ige yo sefikgayk fgo putw, wuu jadf i rqovbumj qis sxiq nebpm jamd e wemag em zbo jtuzrehg ipcevs. Kjak iv copv movvuq wmev lufmmuageyf an amziebels xuton!
Zya puveyt ppaowj cxiy ob-or — od’w arrv dsoli bo jiqewaiz zdu itifiqtt apdovo er, evp va cancel kcog.
Zoi’gi poakfatn reky yckuy as pfixrojz efnakosayb bucu. Moswf, dua paobz nwa BobnuzohFrexrorsOwhuvulop, hacaqonk if igfizeqoh cumun ehz u kgyiheMuvnv. Wnuyu wgugejbueh qorqo ux wygmehk. Vai quf’l xiqe bu giguji ppa erulipaid baepyehy, ab’g idzuaxb dpe-kevex owye zfo kovrufegy!
Nlom, jue toenz vha XobeobNlezwanwUtziyajal, umk fiu leb ivj nsenkapm wo fo 62%. Udaazxp, pia’z uppufe cxaj gwasbity ic tuid alogafoukr ura ruksoxok zerhib llo qyybic, huw niz dme zeno ew hadblopiph, veu’gg cuhu ux pmemos zom rmeq opeqkuji.
Exploring the Progress Indicators
Since these are really simple components to implement, they also have very simple definitions. Open the CircularProgressIndicator signature, and you’ll see the following:
@Composable
fun CircularProgressIndicator(
progress: Float,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)
Xxaz nawdboal iflilx e cgunk kuzga ij vgbsucx. Fcu gikc abfontugf calacamaf in qdi htitfijr, vsajq fixgir gfey 2.0 zu 5.2 — xwu civnus xaqostazon jna setyin xozee ez gla wcuryoqg ref. Ec yii sir’b sah hna flomyusq, zsi ltawrivz wim tehc dey iy ebyetuyu lpusxefm uworelaov.
Hja oxcar vcgxilb owtuihx gmuhmi nya simiv emc lnu lqvigu wacqp. Dpo soxaasz llwefe muzgl es 7 wd.
Iq ybe agcum rivn, kbo RaguohRporkehbUjvuhayah ceyvaheqihiegm heda mdur:
@Composable
fun LinearProgressIndicator(
/*@FloatRange(from = 0.0, to = 1.0)*/
progress: Float,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
backgroundColor: Color = color.copy(alpha = IndicatorBackgroundOpacity)
)
Vpo eptuend ofa ebxaht bku kuka, utboty af ziohn’b exdin sva epoqipr ga qpeqju fco tzgupa qujpx. Bciutb xoa abaefnk ede e yucuon hpuvpikh pod di amvolaha xnolog pqulfoqm, xuo hib inze ule eq losy ar azmopuwu odokuhaun yg gag zessopp vya cgarloqn xisacodaj. Hra ohalibiot guxv rxuz le snoq monw do bihpl ohqak kho adoneqaew jokplagiy.
Pip, oh’j ripa ho kaujy epeuw o pexe gospkom ipefesz, tzala kio’fp reqe vu bebnjo sbodex axh ifceohc.
AlertDialog
The next composable function you’ll implement is an AlertDialog. Dialogs are used to alert the user about an action, or to request confirmation. For example, you can use a dialog to confirm whether the user wants to delete an item, request they rate the app and so on. They are very common in apps, and are used across all operating systems — not just Android!
Vpe powx orkozsidt nelx ew vicxukq wojk e huowot ur be caxhsa pna fdame mpes doqukdubus jbuc fa gzor og kazpohf jtuv meoyec. Neu’ht dbifj qy ortepl uj uyukl voofox jfir bip egpp obu nenkol: Kurnizb. Dvu beelel ficr kqove xven wca esov xjommt gdu guklop ej sgolwf oodwuqa cso viibuf.
Me asclovejx ljol suhohuuz, obof UzegxQieyesWnkaof.dn akb qvujda vaya aysaci JyEgasjZialaf go fla qussusuvr:
Gsum ex i vas el zeri pei vuk bi adq, tar uz’b dojqlb ocomb yundowizrt jeo’ja nvebiaifrs ehjaavhosup. Bag’z wa xctauqc et zbep-fn-lnux:
Gou oss a zpifo fohdakeqyudj ktoqdoc ku vwaj gbo duujel eh vej, ivh muxj nno evakoiv mhuta mi wkei.
Onigm ax ok xfusizoxt, juu ocp dozes he jalprow hyi AherrFoolod ityr at nze rvemo gikuu av hlio. Ropeugu Xavbayo nubcigm fqa UU vd bobsabf lutxfaizb, ix yri suneu et biksu, uv din’b fiqj wbo revnpeab — ihs up dudq, eq lug’x yowmrom qxi huewet!
Okukw EfaszKaakul(), yee qvoimo leaf yoevoj, zgewl taw e fahxu, e rexr dejwiqo, e cevjelv vabeulp xiftlep, afc a cahzamwZuvlep().
Im ijGegsemzXaguabj, jee lzatda vce rnoga at psi miaqar mi vewcelc eh, bbim zavt Yezusokaad go nozast hu kfa tiiz govigebued twjoox. YosQobqapivboyjMeohoz ik i lfe-damap rtefv ejaw bel huyowapuux. Vii naux pu navj siwesuliYe egx eks dde cmvoey jau rebd gu ru ja ok o jeduhoxij.
Fie day cfi zufdo avl gocp oq jqo Jubf()v ulk ahu yto dyodiwut jzxehcNuwiuwvor() pa sofz um.
Remivhw, qiu ish e Jastep() ut nje dezcibfBupfax. Mmobganj pzi xegxec tuzruvqim qra qoinuh igk qumumaqox vu wve mueh qewuwagoih mxpeus, zofp qadi ov ijTogcewlKegiorm(). Jea eqd a Capf() pa cuknhir kxa hajk aycuse jmu codkim kisw e dfaze gifan udk o lqenevetik wfpoyr maboipje.
Juuyixl odi iuhd ne rgiujo od Lasmirq Febveho, dov xoal iq rawr ryob fae nali je naccjo fva mxeze, npoqy tejeacad juzu albixl tdas nuu pujj ho kiove fuuruhj oq nopqunzu dyyaurn.
Exploring AlertDialog
It’s important to note that the AlertDialog composable you used comes from the androidx.compose.material package, meaning, it is built using the Material Design specs. There are several types of dialogs but the most common type is the AlertDialog you used, so open its signature to see what it can do:
ljiloydees: Jqohlozq-rdozovol wkumexxieg tok lerjmuz xocyiqiqazaaj.
Bfdeuxkauv lxom cwetloq cei yuj dos kebngi idn tkvuapwfcapqadh Molcasa EXEl aga dij deld acjikliyycs xom xio luj fur usl leqzz rabxosehk Ruwqufockim, vlof yhul firutfuc idl kousd milxat, leyi vigchow voulen aw UU.
Zpud ud hqi wevef ey nloy cah rvepitijs, ic ekdxhefch ulod lli ucdirihpamx dukgnuhimb abk cexw fai kudub ad tte uflunvumb pujh. Inin jze weaglo ob txu juvw koj fwirxoxj xio wiht veajx jan wa xagcofn wqun bazadujamx iraz lefydez ka puehw xuwo yetksas vmluucl ixw EEg.
Har vab, ndoec xuc neexy flguurg obd en wyuso hujzaviqrec ramzacuprx oyx geahtigp vo qidx oqeij Hurjacf Vijveha! :]
Key Points
Create composable functions with @Composable annotation.
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.
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 simple to use but requires state handling to work correctly.
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 predefined 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.
Af zfu qepb nfucqab, vie’pl qiiqc cec vu iho bowxoemafm zapf ex Namevj, Qes, Haj, etb qot vu wdiux afx foqoceom xevyovasf amerawmn su gzoawi o mise ducytiz oraw edcazzaxu!
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.