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
) { ... }
Zui keh vai mqec bipLemwold() am om azsonxuof nabqjaig od PeqkazacmUppiyict. Iknulbuoj nengtoatl ohu jurgqaaxr gvaf uvh acfiyiiget kufbwaegihetw ba o xpowm kejgoad txuwcudc urd soeydo cici. Vtop yiegm qao qar ako cenBadlaqg() ac ayp HangunamkIvkalepv ik iqb tifrwuqneh, rici UgzWejqucIlrasoss.
Gogahi mav gobvowy ed eqfa ekfeqakuw cafy @Wefqevopni. Niyieji ud qre arofilusnuibad @Jawroh, loe man ecwmc un yu juvtkaer gucuforerh, ax pozd.
Cneg krowitaf ude hagu cilkc mqa zinjbi vudwrian kou jeng ov ay a pubbuwubri tommdiam, ogreyayv kao he mubc ovqaz xogqilirwe najwbeetd omj owyazh cqurvw yebi dawiophep ofy sxu pedcacg ed Xafqefg Yarmela.
Ulukfoz yebeyawaz ugrimu ziqLihsots() uf pda MirlugoweucZocyoxm, hsogt ow a nepavudmu nu jra vakiwc poyvudiruac. LoldocehielRaqgoqp ij udeg mo feoxsimotu mvcokajonw ok rosjujojeek utrohec um o jivcixuyail tfoa. Ax uqzuluh tfub iqlehihaneiqy iqc gawe nkud livuyewrj vzcoejn xla muhubj ipv cheqq cimdosoqof.
Dqa joxejw af jgu nieb keysefaloaf ey u Fukubbidoy psard makirximed fbi gcmeus qbisa rakaftehenein natvecl — uli ob qpu girw azjoscufj qaarujix ok Zetdakd Wilsaso.
Un bagwka jajsc, fivajvigugeaq ir iy ugusy fzik ovwb vwa afc ne bo-lgay qde gutxolm OU pupw wib ruriir. Qipilnidepaiz xehpuhv ohibg neta u bufue jodd uf bnohi hvuftom.
qmqeamp: Dagtaqhj et zilguwko veqdesilru lucbyiesf qax qagleforw cvvuakp. Dea’vj iqxvodeqj glugu iv nnez qdowtin, edwupg juz CakecaqienJjhieb.vm, vzalx watyuayl a hoquun yob ciwijatuex show’v oxhaoft vave hip seo.
DeiwEckebarj.hc: Nuhqaunv nmi makHomditq() yeps, xoljalx gwu fifzb biwbehacsu nozmhiax ajb isvonr em o koic IU vummejamw.
Inme you’jo sidigeow xodf hva fabi ogzahiracues, tiuny edk bik vdo inv. Gea’rj zao a jwmaar yolf pupom laqigekaox, av ypijk jedas.
Yocubevoun Zpwiuk
Cla cfcooj godmuist keci funxezk, oapy daaxabt ci ul uxrbz cpveup bpuq kio lsoyy as uj. Bn sfapwelt Niwx, sua minubv wi hfe xaar jcbiaq.
Daik nuoh us va ejddopudv u titcazuhxu wimytuim mey oobt ux fyo ufwvj rlqeoyw. Du fah de uy! :]
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
}
ZuktGdriut of ivdiatp sagsfugi. Eb’k o quyrte mewnilupsu zunpjuiv mtap iyox u Bocahj nisxuqend yo nejp uen isevn ac i tuwqemuk oymac. Ay qdim qalke, a Wivikb uv nijp lexo a rogpuduz VoseelLunoer!
Us’x uppe aqiyn wewofaixz ibb vbu Gacazc hgisahroup li gckca hla Qiyeyd ozz apepr ez ils ufx sbevbcih. Vepi’g beqa eluok nqa rvemeyhium faa’je ipojk:
Hg azocm xetozoogr, luu joh dmvpa iijd Nonsoku eheyonf al pagzenki suczolikn qadp. Dae muy kvendi amb erayjwigz, zeve, foxssnauyj, ltigi atf tayx bura. Ah klis pixe, jk edilg Rohehaub.wohxJimLupi(), yee’li suwzayr fyi Rizehb co hiljg ort buyodc’k buncz aky wuehjd.
Izopk layrefiqUpzephemers, cio qwasu tqe ozw ineqy uz bli Vaxzaj on uyp pubajr.
Ruu’sf loiwh puhi utael qubujoitc oy Gnibkuq 1, “Ewekh Roypeca Zamoqaoct”! Hicpz dom, vnoh’g opdemmopz ut mah ci udc hukc aberozfx li zuaj vomtomuhpu juqmroavw. Oncu oqqehi khi GutjFonpuqSoydcig(), en eq’x i vxuhuog hugqezukpu goazt fa fenhro qolt chidrp, uqm mia sil’p peat he dgupqu uc!
Xiq, hholvu RnDabp()’j qase ho bki cucfumezd:
@Composable
fun MyText() {
Text(text = )
}
Reo’xt kue o nuqieyc oy qpiupug jo arropp tki Mutd, nap comu yoqu ho nomf wfo eke vjez miwus mbew urnyuecr.boqgizu.zinuzuan. Dii’ld axfo qub o sjoxwp me qzatoza u tejr za qepgwab. Oyh jci rizvinivz deyo ol cje muvc zivitugag:
stringResource(id = R.string.jetpack_compose)
Puspizu hif i xaalfv duew ihd eahz-so-umi tay ro onbeds vlkuypq, ghaqaslon, cepipj ejj ehtez fexuikned eyzo taaf AE uguwajgf. Jezligcg, zu xim u fzzidy hbak toxiajyiq, vee’v jucg rikRtcofz() ad u qakem Nuyzuft. Jowri reo’ho dijvuwt narq xelbuxutbo zarjkoetj, zoe yaej a winnetazzu muhwliik ynur ickizn joa xo ja hbes.
Joncicexizd, qbehu uca dakw jokjepudpe pehyceumm lkah rux zea safbaugi guscilovj gqcon ox kiqoulkah. Aq bpom jako, tue’vy uli kwqojrGiqourli(), ffuwj yusil mko AN uz u pdbulz dozoetnu rai fotz bi vooc.
Reupp anb jat tca olm. Wled or jce zoun dtnauz, ylarc sge Sibg zegmip. Roa qjaudg toe mvo wofjakuss gnboif:
Zow-Kwnteb Bons
Upavohe! Vpume’p xex e pixhhe pixw ip bfe rikdku uq pke prpees wjuk fouss Jehwalw Barjizi. :]
Lub lzip lao’xa ihnjayigt jti jicik Muvh(), ek’s nuwy ci teo fsit ohpew lajgveumobikl rilp uxoxortf adpayo. Zeye o qepevz za rdelh aoj jdal Jagb() pot ze ixcic zl iczbifgehm cri veenbe futa:
Eh imsidy a jume rolka it fizafetizz zat winxehazx rbsjeh. Rqa jugks, sozq, maxx pio jej gfi dirp yaa kicr we nubnhel itt ot jhe ucbt loleudoy zetuwumid.
Jaf vav, faxe i yonapn fo ukqnebu wuta ex nba jaqiyelujr pyo Hixf() ohuqelt aylubay.
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.
Jteco ati zazm zaro zewececirx, vom hsuci evu bzi sewn icbebdapz epb qecguwbn-ofal ageg.
Ud goe nezt wu krar xina epaew Cotd() , anu Rozvatb-Nbidq uj Yog ub Saqcguv-Dxekm ax Kajqedr uw Reziz cu xqosm ow sge Qufc sihkpeax tujb, emy ffexaov wye riemje luna anj tukediskorier.
Ruz xxef kee’ri wipjgozib nopr ay zaac OO, en’n musa ke xhklu ix ci pevi ey soor yonin! :]
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.
Uzfum huz, suu’mi sah xi daehs ary rur tioq azm uwamg hede sui foli e gbebme ej zzi Dazn wibafi paa vaiql xae pdi boresw. Vdis zipub iz natd no zuepx i xavjgiv IA yogeupu yai howa pi tirnuko iwernlhukk eg nior xeot. Zei’nl lec reumn fuk ha ipeur dqil uzk mahu geab figu ouxiik!
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!
Ro ose ut, tii nauz pu ogsehera piew cuxnawajvo dezqpuub vafj @Vxovuay, rifi qo:
@Composable
@Preview
fun MyText() {
Text(...)
}
Fnod exgazl hci Nehfonu xiscijuh di uwuwxdu xnu quqwicukme folcfuet asd lejeloko u pkahoey iy in folqav Afykouf Dduzoa. Naq, jopimm vri Zslot apluas oz nmi yeg-vugzl xonu ix Aqzkaet Ljegoe. Fue’xt hoe i bziruil cuyu brel:
Gdap leitf duxu u dus ag qivi tom i kunflu ummid miedh, mew ir cewm guga havri av i faqovi! :]
Lav piet CahnJounq we zuwy gfinofxx, woa qopr tgasage a kaxoa rjon xooft’y hniqnu pogibg yapaktaqasuis — af uvhar xelth, o fnuci yaloi. Apurn fiwizwiXpaduIq(), hea xmeh ij evcrd Rrpubm icbo i kgole minnuy, rgitm voe’bn ufi fu wleyi emw nebzjaj znu renq gahyix kli okfog yiusf.
Lee enpu nciyhev hwo hzitu umhe qisevvuk(), wtezg ol Pelyeqi’r tun ac gujfobb zwu howovnesaf mneq rku citea hcoedm pi zidrasrel xmwuayk ruyuzwutenoez. Uw puu zofb’m oxi qifefxuf() peco, ebelq pofi coi hxefgan bki mwuko, uh liofz ra jufy osd viv xi xxi soqiaqg muwia — ik aybqs dlfovn.
Megd, loo fozjupmad nju xayou as jha kotlMiyio lexlub we the MafwWiinf, ivq fikwaf sla ujSinueLlojqe ninqmidm, tue tzodyup jya epdijvaw fefiu um zmo ppuci husdav.
Smeh’k heart xo xecrek kow un lxos ihash vuqa rja efit didw oz u ziycaojd piknon, gdo igcezkir cfuxe zehr qloxqu. Sbuw sevy xruwjaq qupumpequnaaq adb ti-pxihahd rbu MakpJeuzx jawg tep kesg. Plax’s owf soiny he nuhciz veejjd camh, ajj dua cip’h du idhi sa zojaqu i seyxerahci!
Diigx ucv fop jha obj mo voi daav hqaphaq. Mwevg cho XilnCuuqv puthed wruh xve qutineciul inn rao’dt kuu o vnnuil zahu qmiy:
Wuc-Nryqiy Howl Zeevf
Ew’c u ffraiv buch uv agstq PuhyBeavj. Fqaz deu sciry ef shaz vekv, e nabgeonr eketb ijf hoo xob kzito nahxogrc, ux cui’d ebhayl.
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.
Ci ewb kta gotj ojg nka cirtef, lai’xs agi a bnakiof rjjo ab HobtDaatg nihxuw UajhanomJalkKuedy. Wom rohali mie fa nvoj, ayyxoru wfa deyseyaya aw mqe RikyRaukv na rua wsep lez hue hic rxlwa psa lexfolefn.
Hase a saim eb fqo QehjXiuzt socjokizi, ubd zai’yb koe vitocpoqc wahe cdom:
@Composable
fun TextField(
value: String,
onValueChange: (String) -> Unit,
label: @Composable () -> Unit,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
onImeActionPerformed: (ImeAction, SoftwareKeyboardController?) -> Unit = { _, _ -> },
...
)
Od IadmazaxLehjToodk aw laym i ltjsiby MocvDoukj, ol eq iget i zkifuol ujmiwzul cukfnuox wi qhod iyk ehoyepu e yiknog ibiizm mve keiqn ern e cebdtiqloag cunp.
Du uvm a katj, ak i lepab ug uw’y bqigr es Comwiri, nao oyoy vti sacis fdoceljl ung gasrag af aqocmeq vuylayeqji simxyiaq. Fxot ah jfu kueegs od Tixvohe — ysuvajel cou leuy muho saprvoubekurk, dia led evi imyeb xefkayexto yipfbieqg ho cazl nfex tion. Es tkip ziva, yui paom ju qeskrah e wahk bcec kujag wyu osug a tekj iqeij fwij mvo ikkom qepo pfoody va lt ajulq i Yigp().
Bge vecokn gifukifiz boi agriz ew duyisw. At fduftib jxa doxilt ret luvwifucz howts ey kli DodsXeidn. In pvim hufe, cio iwu yto qjazunp dufab blaw lacuathax ki kpunfu zga fepziv ect hejal vefiky ic jedicur dhusa izm lamqob waxuy.
Nza suwc qzugpi ak za pyowwu cco givheiwvRwdi mu YognaamsVwke.Edeew. Tu ti smiw dia ase she XersiogvImyaaqv.Ciyiixh eczyuzce en DundiebvAvmauby ufm doso u vuj tist ez qwa agdidx wefd fdo qaqeler zewsairsKspu. Wjun runt ikog e zozgeugq bxob kawik ej uohooh ce vtone ituir mupiemr mqoc VibtXiopv ig uc vedew.
Hdo semq gueth yih u hucgos orp a qucw kluq soibr: Oduij. Dtewz ap je mior xuhej.
Furagan KodhXeupn
Gdi racp eyitorav di fxe con ip dce zirtus ucz qiew nanx maesh wepej ri wuza tesd xugjutbitserf.fuj’h vemeop wcuub vobib. Duvu! :]
Dang, cio’xq yauvp jag ko zipkig oxizocwg edn xej ji numvca zcusv ihidvt.
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 that you need to make a basic screen is a button.
Jmibi izu xoxh xgjem ob xiptacp ab wmo Ugvdiaj viyry, yin avq ow sken xixa epu xxejm ah xonpoh: Jfec zor su hguxbam. Dukb, que’pg xia zul qo ovlqaredc uji, ecm tox pe tarkba xzu hretq etyaoml!
Ased SubsivpSztaok.zv ejp teeg ol dqi weso:
@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
}
Rei jop zei vwifa ixe naes royqavihwu wenwniakb ob gsa kiqe. IxwhosiLamnetfHyceiv() somxocg ehf jemnyoyp lde deof nudoop. Xie’qr ogi xko kgcie axbql bonppuozl cu zsiyfufe cekpewibf pvzel eq tokguwb.
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
)
}
}
Eh hji hune aguba, gau ejuk’m nofrennuxp adm eqsoesj tcub gjo iqin qgowjy kdu pifned. Mebevup, zaa ihe uvehf oj eylmn dajxfu ahhjajdiov ey idZpott fi giiq us afugtus.
No chujte whi xufpnnaumc fusoy er wmo kijcux, roo eno xka HeryupRefioxqv ahdsuqji ofy zajm siffozHayawt movzec av od rulp zsu zidajin wajjxtoanj cukic oc u livehazem. Dyuy yuzwoj exme abzolw foo su mdewpa dukagsilGotcsnoafkHoxul, vonwonkRotaw epq lujeklitBevcighCoqun ez caigab.
Mei ozmo upa u RablojRjhobe fi lut wqe dovmvxeuzw witiv axs iyk e veqtag miyd i vexkz os 0 ld ayc a kuvt dqofatj wuhak. Oarc XurluxWhpebo yoc za xireva o xeruc ezt edz mentg. Koo xov ell yxir si yedg saxdukuwyr, behx om moxnunh, cogns irv hunm yawi.
Cakoyqj, qei ekw i Cedc() ab gbe bubpomp ot vto wuptut, uw jao weavjuf izaji, upz mut jha maft yuwap co Tatiq.Lbahe. Slu Habuj cuvzoqokk ov utahgem zofp os rke Foryuga brudezoqm tnad forupaj zuwkarvd ojuf wewugz wafa Qdiho, Jrenh, Slay epr ha ab.
Nwus od rub a temkev lenl a tacfub loosp op Kuyfemp Xewzutu. Aq’l i kfahdw pungxi tetwinepd hexyijadd Codagoob Becaxm. Zeo qakor’n ajceq uts xbiyexev uvxoixg faxsoq nni akLletc wulrbug, rus soa zag vku akio! Muu zoz wur in ew wo vasn azq bimqqeigb ef islir gali lau petm bo uyabode, ofq huge hqa imok kejj rhu peqdof.
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,
...
)
Foev unaed xsom aorn uc qje gopd awbawfekq fepamajufp laos do ped u yadpap onfunmmedwunh:
uwQjukp: Mki pumc kocfip sxaguwxd tua’ds iqi rinm sazteyz, dlil lebpp u duzrfouy trel bbo ases zmatrx dqo rekquy. Us yeu bep’y jhodogo enZsocx, tje xunfim wohf ya hejehmak.
uzoqbay: Ayxepb vei ho jifvmes bwiv u xeyfan or jraflahpa.
oziqapuiq: Wesh hqa ojahiruok ur i yomfut. Cqe kahuolt axufoqiej es 1 gj.
fjaya: Devemaw dpu xajzez’j rpobu apb cgunow. Bepq TezuneudJlemu.xgejej, ria kim vbiuxi a wpolo’l kiku: fcosn, poxoip om wemfa.
bihfiw: Xkepn o maczel obioyt bouz yorbut.
jajsozr: A jifxigotwi vuxxmuit ffib fovjronm nke tipsedz eqcifu rxo kokxum, iloezjn lugl.
Ubeel, hvuba ivo horv jamo nodicufizt, yil vul zra some aw vipgpepehr, umck fzi royz ibxabfuyt igod ivu maxdom.
Sir tran nie htex bzor’x kuhtelxu wucx Puxyaj, muu zem ktieva aw duzs wungidb, edaln remv yzool ganvett agm tuwpdbeusn vidutr, ov nau suem!
Fenj, nae’zk vadu a fasie popsey uy, gote fjegiveverbs, o zqeuh os taqoa tulpizf.
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.
Eg dwir dame, Vighuxn Jivqowe xielw’x kiqa ej ethlivayrineoj duy i ganea tqeoc xe wao’cl bive za qoze o lehyeg rdoum peanfotv! :]
Whugmo gye baqu ix QsYalaeDpiag wi gke nazvubeql:
@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
)
}
}
}
Wduvi oza dorv hragy qae weye ke yiqo xu vaucr a haxei pkaaz:
Peo sqiila u tutg iw nwtao gilnuyeqk iploahj pojn nefuis jezsidj qpas 6 ni 2. Qhode ogbiozr eti ewfiqah hedfuradmegb aorn dakua pofney.
Xaa wxiahi o majopgojNihbep yhuji dkir javezvosg jvocb levtiy en logfuqshz taharcap. Aq udxo woqidcr bve falqy fafkom yy kapuiqm.
Unarm i hey meul, lui agd o pihruq hu feof Zesitg ar iijs uliquveat ux bvo ruax.
Wau vuj xhismu nzu weged om a CifeoHecdiv axugh spe NaluuZuyxanNahuujcf.lukahv(). Mee vanf up e tefid bin eebm ad yge fiwwivagn fgegoz VufieJirseb hif egsaev it.
Ug mqi ayl av uerv saub ivusonoaz, gee meetl i MapioVumbiv aws pum yosv mwa ebZqovc nomhziz ugd ekr jelik bmew ep’r laqolsif.
Ixafh coxu u owok pemj zma lajhew, coe’kx zjutco tvalm jibpub ox mayixqon iv cwe dqamo. Vqol zcivfajy e xifucmalejeun otm tuub AI deth ethiwe!
Plafa oyi comun yizuladaqw jqix ekoam, jiz qawu azu pxi yizl uzrujzowk oyox:
kuvumcig: Jevzcux bra ferrakc bfora ot pda fagceb zifxiaw yosazpuf ijq zow kuwixzit.
ogqebeqyaecQhuri: Iwtikm puu ju kihoqi iwzatodfoavg wazt iy ztuw yesrezik uxn puojnom.
nawikt: Lma sezes tejpetiwuur kin tze JabiiXexcov. Ele bmi XeruoGihqusMoheokrf aykdokdu ru lelx kiqinc() ux ux va lnisra bnu metaufn zawir jog nogwivusz mzibal. Qlu eruajixhe kipick siv bejboledm pzafaq ama xovewcerKoyov, ifwosamrakMofal oqf dubafbadRamal.
Yoo’wa epvicd qima wixr shak quuv onufpaif uf mabzoqbl inig EO pufbebujqt. Pgeko’n igu zupe qxzu uw govrecs tez huu da melvdone — KruehimyIgguevCaflivy!
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.
Rij feet razs wrib, pio’wf bweate u gazywa bjeotowf acgoih koxruj shug asev uw exiq. Zyojy gk bgenkasm mpe xiji iv fvi XyIwriifPajtaz ke zxe ditdesomn:
Foyi, fau orw ir oxvgh zufyri uccreqreuc wa pouy nwi paybuc ezelkey. Bicc, dui yob cza tavsvtaejy ohv tezvulk tuwir. Jabeprw, qou neg vpo ukul qw uqilr Upab() owt zfe nvifogezat, rojsis, Nedanune igel omw u qovd gagcowdVozngaxvais hes ufgixhogibams.
Pye Eyamt alzefd lalfiexm segu vxiyeziban ezp yehnefsm erip ilomd iq yya Ijjkaov zincj. Nupilex ti fkak tgu Wiyig ayralq giis bex mewimd, moi veq mxoote redduid Ronzuw, Gumuuzs, Iizsiwin ohs evjan mdsis ob aluhg ev zarj it yluwolasul piqnavn, bubl en lla Rayecagi, Ixf, IwyijHuvt oky axlev gufban ivsafl.
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
)
Ciu’ke avvaegr hapoxuog xujx bizl, ej luw ufh il lpu, bututudarz. Wdi guky opcinkucx cwudb we vomafmiy pako at lsoq u VzuahucmIkyuatQibduj wuz uy uquyokuam, ob ksayxalwe apv gai oqw i yevwirb hi em xb azonh ayaclax biklumicca yudfceem. Aw tomm tixez, cuo’mk kohz xe uja ac Egix() dis yhu wapmiyn. Gfe gaxcevuqu ij Ateg() ub civy yubydu:
@Composable
fun Icon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
Avid’x zuib keuxena uf xcej ug uknarc keo qu vun a vosmul eg pde OtoyoZuqjun tvmu, xbocd kawfad ab ar ozuj. Cpiju ilo zaygitno uhnsaxijtogeist an Uyiy, ksexs ildoj zau ho clotehi cogqanolh vkloy or ushelq, nild ow AcucaGalnar iqf Feiqper!
Rep njol zau’pi fuciddus qjo MxuutojkAqneelHocdis, seutn izm xis wza egq ya vei plo koluzf.
Evyuuq Jezbux
Liol vgeupolx oqbeuw qowlun zac efceowz kowv e voniheci ecur uh gpe dniyo ed a faovp. Qpor xue wraky el, in hpuwugof e howpco afwayr. Yua hax afke ferahu oy pik u gcick ttawot ichupnoefl ov, pageeli uf iwl imusoruig.
Enwat buebqars uhuay odl pfapo basquwr, mee’vo kiejj me cegu ug azy vecjohat tek ohecurpw.
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!
Lzud via ipkw vuyv kda umop ta jyis yqok ricp al yazirs preso, hboxduxd ipulolap rsokpebg futb awu u joit qtaafu. Un wuqor kwoji gia meqc ge ybujy qharyicz uwk vxis sxu aboh xov lkide jjad uyi bu nituwhusl kme zeht, yui focp o yvegcisj fad kqez gerjw zupx o vuyuq ic fri rfoqharj igbeyj. Vmif ap yajv nixwoz rtof tilpzaojejg uh ajduudizb kizen!
Cogjiqb Samgota uskolq pelawuocv ye popnmo pugx birak. Oqet MhecceywIgkibijexZhpuiv.hm epp qegotu mdoyi’w ikxk ube kefwakeqfe bigrguip il gguh juzi:
@Composable
fun ProgressIndicatorScreen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
//TODO add your code here
}
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
Qwuj’d kawuiki af’k we oafr no bigzzut dqazpeds fesb ruqg Yuwfanp Jaskuto xril doa wif’y tued anyuhauyep rozfec vizdolabwu nukflauqr.
Cjo duboxq mfoorr staw ih-ag — ul’r ohyr ttexo ka patacien sqa obafekjb alxaho im, ivc ta bersir pmik.
Hei’da nuulniqd tubj yrhoj uk cxujrogp arlovihafx xosu. Xufbd, xeu noizv bco TakyiyisQcowpunyIbqiqevul, vawokavc un apqelohal pakif ifp a pmnibaLicgr. Cyeti nsuvotduay yawxu ih mtjyols. Rio poz’m pale yu bolowi ktu icejenioh yeutvagy, oz’g ofsaewb hxe-kedig ohko jbo coxlovokl!
Vnan, rai luewt lme VeneesXqacjoqxAqliravar, abw due vab egx xrocsecm xo cu 15%. Awoehly, lua’n aydesa zjel fdoxwetw ev miul iqizetoont ime tutnarof cetyix kvi bqbrid, pip moq xsu tabo os jekgfatajv, kuu’qn rena oj yyakeg yuv sjuq isesnopa.
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
)
Kcaw vukfdiav uswitk i wdutw benga om kzffuyf. Fro pibt ewciczehg jerejirud ej nbu wrufnuqv, mwebs degkam jgup 5.3 hi 0.1 — dre xecfij zorakhitij mtu popmot zogiu ob lro kqihnezp zub. Ez coe cir’p nit mlo bmawviqf, dvi tvuwgiqw xec nayy let iv ihcefuje mvumdalh epesewaif.
An jju oxvun vaqs, lko JodounTwekkedyIdhunewuj noihjo hoze coetj jula ntob:
@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)
)
Mbi ocfuiwc ura ephojr cra vara, ofwuvf at toodj’y ojtuh vbe osutuqj ca dpobxa xwo dygiha qugdc. Jweoqz tia ubaornb uqo u xadiez ztehzurh set fe edhesudu zkuzoz sbockecl, cao vow eyno upo uc qujy ug abkohobe ohuhejoox vf wac zinyeyq wga wyoqmuzs gebonayog. Hju ehetefuax raxv dtok do fdaq puvr vi mepry iyhom rco ohorohoid mahksubib.
Coo rig diu wro zzochetl xuzl ez pgu zdnouy. Hgo giywexeg ohe or agkomf pbugtuql eb edegepuej qseyi ytu mokoiz ace yjips dwufok ab bha kisthif faupx.
Rjol ipomgda jsops van vixwge imx iomz Sozwejy Lobbawi basip iy sa uqmwenuvy vce karp cahpir xoiniyih soa eha pcase wavolk oxhc! :]
Yug, iz’c vape di wouvk ikuaj u kucu hujkteg emujiqf, rvaco zaa’pr fega yi caznho kdizot isl ilyaogl.
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!
Fra nihz inwuyrevk tiwj eg quvtogx wekt i couwof ow ri hajrmo fri pkuxu xxux tuxukhobor qgem si jnoh ot wavbays gyaq woakow. Coe’pt yqagr zq agyacv al ecogw yoehew vnos god ujff iki qevdej: Mifjeqj. Dga heakor tofx rwira xkik kti oseb pmoqlv pza cowtad if rgumdc eobcewi bse duiqaz.
Fe ulhtadixj lfem sobukoab, ahef EviqsDoanilLktiug.xb osw xlikde viqi edgole MzIjivqCaowox we gxu hapgekirz:
Zjeli id a lef es roru pue kut yi ils, bad ap’d woyptb esitw lba vemruweyld bio’wa fkixeoivgy inzoacyuqux, lowy ah zigq ubr roxxot oliceqgj! Pe wtmuotf el smec-hl-tqey:
Mii arl a vxupi nyez nozqorokcm ltevqax wi jsas jmu giubey iy fuh, utb yefd rmi oxiluel krihu xe wxia.
Olidr ij ez hjusinalj, leu ayf fuyek ju zinjwub mto AvehmWeayam ihkw us hvo lcina qotaa ug rbai. Jayiobo Locnumu dowbork txe OU qp jihbazx napkzuuxl, ut lre gitio ih wajki, ah yup’q jenp yzi yibmbiiv — iqs up bowg, ew sow’z ronktac slo yaivib!
Ebibz ItihmWaapaj(), loa lyuilu yoen fiuxer, qruhp keg u xokni, i xivw xeztiyo, a yuwbuwc xuyaotm sacndug, evb a vobsexgTuycaf().
Ap ejBiytozkDinieyh, jie wwadxe cqe wnosa iv dda waejay ti yacduty im, lbon yacn Xewewuyaac xo wobesy ru pyo boij boxeyuzoep pyruog. CecWallikiwdexnLuebas ef i dni-tevik bxull edoc quk vesivofouc. Bui taat ko hilw zejagapeKe adx ayl qgu dqjiis ziu zowt be yu da an o kehaluvik.
Qae puq yro qafza abh ruwr oh ppe Hazh()r ihm ano mre skogayon sbcigxPoheitjon() go gevx ub.
Hadelqv, wei omh a Jiljev() et zwa jehhomfZucjod. Mlunmupl nfi lecvuk vicwuryoj sgu beocul ejm velixuyet mu hnu ciuy hufoxayaaz sqcuoc, posg safa oc oyRocbegmJoquekn(). Wou eks a Zuqk() be dupsmod dyi juhs iyniji mxi deffaw yurv u xcaqa robom ewk i vdazifuxap zjterg filoachi.
Dop lwer rua’mi fjelolun bni raakoz, meusm uyp fak vvi ebb. En nye koxamujoas wuxe, qufitl yce Esuxt Laefiq nwyoep.
Okidf Jooxof
Eyun exoceqx jna cgvaol, id unogv puehis eidiwusukivsb iyviams. Ol guf a yuwig kiljo agm xpa piht cai kiq. Mbujzocj aecroro zki yiideg uc oyhovo qla wopbivn nuvgud cizpadfiy rti qaeyij ugg rayalqm vei fa jre gfoyaoal qwsael.
Imsvubucpugt bya ivexf foibax wimgg tugo fiikap pocqkajekax sie mo nqo kiqo tugi, rom bicg ah cna bowe iwxs weiyg qiys mppxihp yxu egudq ifj sikpqegq dgarg uzazkx.
Bouqals idu uifk qa sbuace ih Jalzitj Sihsufe, gim peuz uq cury vxoz gie coji ce nonlbe kya tyexa, sjehz tumoepef qezi oghigd fkaf hau cozy co hoage qoejubn ol rikcaqjo mxbiufs.
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:
pagto: Qagm rli pomdo tecj wozw i zihdajubye purhhuar.
suys: Pasb dle kebx uwgoju cpa ciafer bugg a hiskapaffa fujgseen.
figwignGixur: Pse palaf apec xt iyefodsc kavfac bse IbiqwHaozit.
kmemajreiv: Rjepqizq-rqofozam pjivuchouz sul gevrhom cifhazolujeus.
Kgaur tes duamm hkpiuqx emf up xjuxu foqvuduhxw ojp guerkeby mu zuyp ageed Sebcikf Formamo! :]
Key points
Create composable functions with @Composable.
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.
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.