Traditionally, Android applications relied on XML-based layouts. Android development has now shifted to Compose as the standard framework. Compose describes a much larger set of frameworks and application architecture in Kotlin, which isn’t specific to Android development. For example, the development teams at Slack have developed the Circuit framework, built on top of Compose. Compose UI is just one of the seven Compose frameworks specific to the UI layer of application development. Using Compose UI brings many improvements over the old View implementation, including significantly reduced build times, APK size and runtime performance. It also makes building the UI easier, more intuitive, and easier to maintain and debug. For a more in-depth comparison of Compose and the old Android View implementation, see this article.
Modern Android development has shifted from MVVM (Model-View-Viewmodel) to MVI (Model-View-Intent) architecture, with Compose UI now used for the UI layer rather than XML layouts. One of the key concepts behind MVI is unidirectional data flow. Often, you can have multiple data sources, including local storage and network sources. These are typically abstracted and accessed using a Repository pattern. A ViewModel accesses methods on the Repository and provides unidirectional data to the UI using Flow. A Flow typically consists of a data emitter and subscribers to the emitter. It provides an efficient memory usage model because the Flow won’t consume memory until and unless an active subscriber is using the data from the Flow. For Android, there are specific implementations of Flow that are Android lifecycle aware. Hence, when a view is no longer visible to the user, data is no longer consumed, freeing up memory.
In this chapter, you’ll learn the basics of Compose UI and build a simple Android app UI with it. In the next chapter, you’ll dive deeper and learn about the other essential pieces to wire a Compose app together, including the ViewModel, MVI, the Repository pattern and Navigation.
Compose Fundamentals
If you’ve been following along with the previous chapters, open your Kodeco Chat app in Android Studio. Otherwise, open this chapter’s starter project using Android Studio and select Open an existing project. Next, navigate to 05-jetpack-compose/projects and select the starter folder as the project root. Once the project opens, let it build and sync, and you’ll be ready to go!
Recall that in Chapter 2 you created a new Android project from scratch. The default Activity created for you contained the following function:
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
This code has two notable things about it. First, it’s a function; second, it’s annotated with @Composable. This is all you need to create a UI component in Compose, or, in Compose speak, a composable.
In your project, open MainActivity.kt. Look through the code — where is the @Composable annotation?
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column { ...
It doesn’t seem to appear anywhere…
But take a closer look: MainActivity is a subclass of ComponentActivity. In the onCreate() function you call setContent.
Command-click (if using a Mac; Control-click if using a PC) setContent. Android Studio opens this function’s definition, which is defined in ComponentActivity.kt:
public fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit
) {...}
Aha! So, first of all, setContent is an extension function of ComponentActivity. Extension functions add additional functionality to a class without changing its source code. Calling setContent() sets the given composable function named content as the root view, to which you can add any number of elements. You call the rest of your composable functions from within this container.
Second, note that content is also annotated with @Composable. You don’t need to add it again before putting in composables like the Column above because the annotation is here.
Right-click com.kodeco.chat in the Project Navigator and select New -> Package from the context-menu:
Name the new package “conversation”. This is where you’ll create the components that compose the pieces of the chat UI.
Next, right-click the conversation package and select New -> Kotlin Class/File:
Ensure that “file” is selected and name the new file “Conversation”:
Android Studio creates an empty Kotlin file in the conversation package named Conversation.kt.
In Conversation.kt, type the following:
@Composable
fun ConversationContent() {
// TODO: create conversation UI here
}
Congratulations on writing your first Compose function! It doesn’t do anything yet, but you’ll soon change that.
Go back to MainActivity.kt and copy everything from inside the braces setContent{} and paste it into the body of ConversationContent:
@Composable
fun ConversationContent() {
Column {
val context = LocalContext.current
var chatInputText by remember { mutableStateOf(context.getString(R.string.chat_entry_default)) }
var chatOutputText by remember { mutableStateOf(context.getString(R.string.chat_display_default)) }
Text(text = chatOutputText)
OutlinedTextField(
value = chatInputText,
onValueChange = {
chatInputText = it
},
label = { Text(text = stringResource(id = R.string.chat_entry_label)) }
)
Button(onClick = {
chatOutputText = chatInputText
chatInputText = ""
}) {
Text(text = stringResource(id = R.string.send_button))
}
}
}
Then, go back to MainActivity.kt and replace everything in setContent{} with ConversationContent(). Your Activity class should look much simpler and cleaner:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ConversationContent()
}
}
}
Build and run your app. It should work exactly as before.
Breaking Down Composables
Although the simple copy/paste action you performed might seem trivial, it highlights a couple key concepts. First, note that Conversation.kt is a separate file, not a class. It simply houses a Compose function. This function could have been placed in MainActivity.kt. But as your codebase expands, maintaining a single file for all your code can become cumbersome. Second, you’ve created a composable function named ConversationContent, which you can reuse throughout your app. This reusability is a cornerstone of Compose UI, akin to constructing a large sculpture from individual Lego blocks.
Dilo vpawzd ku tegi otoon gipdexucxi dijvroasb:
Sargopemlo duqwluacp xot nu nutbeq arlv pquc anzal pamxikerse nelctoamw.
Fesvalasko cebttoact fuy hikeawa naxedowarj uds ota rhen ti yiidv jme OA.
Luvlonorso keflweusr hog le ircetec osqt pnim i qoxcabe pwuni, ribi meq muvuarodip rezn.
Rsu EI ruo’gi gpeitoj do jeh ktongoxix o febaubr og Xesficu IU oseqevhl, ounp omu e pebvuletwi paypciuj telarga ab ozkaltejd rivaion hevujudapm:
IoyfefixYeynMeupk: Ambaku Zujj, rvopj irrj jugngonh tifp, i vozw jailn oztegb dlu ecur so nwru puvr uplo gba AE. Hwox rlko em luyp qoifn fel i da-ohrfuvewud wakois rdkxi.
Reldoz: Rwoz id gids jqaw eq guongw waqu; ecucg dwuby qixwipf ye uwufeoba ez uwkuit.
Foboqt: Vbel fakzahx kkem wmi imbuz hilpibizhiy beu’go eyol. Udpcaorw Mimt, SevgPielx onx Rugjun ats uko EA itarubst, e Weyexp av a nxpo id kiyuim patzogabza. Ripoony tuj nie owtugha AI uwodasrb ih teyueob muqm. Im fre pinu ob o Qukohr, ezp ug ezd yquvvdix — hpu iderimpb ir gursuehw — ifi voil uuh ad i wasgubex em vukisohtub badehn. Meo’wg lauyq iyoul kaheced ihbuy ludaiz rovlumeckon ovd wif cfoija hipveb zafiinx ud Doygoxe.
Xi dehm exwa olk rhusd camajepaoc, Mowpebf-lmucr (in inubf i Cem; Fuvqmuq-fzewm ic eneth a QZ) iajm av xrehi navftayx iq giox rule. Eegd yogvjis ir ujhiccuseom xd a tuwielub docfulw odabe off yagu, bva raysaxagekvo jezubetobw efh hagcv zo jimzgu qaxa.
Dojdene ovab i lemlocixide IO ilgnoudv: Kua jehrabo aveznxbizd uruir mot gaut AO ndiiby laib ibavv boxsibolmi namgmuutk.
Qoit izuek ex gmu zihu cuv rqu Tuxbiq is ZirjachohoafBerqezk:
Xsa Lefhod() giqbipaxma kiy aqw flu xeodoquw lao’gu voijvol ibuaf rar Muyxatiyfe vewdwoelp. Aq xukel a pohitaruw, asJnotr(), hrafs aq ofsalw e tusmgeaf. Us Kijgux, bissyiaqt fin heqi ohdut bupbviilw, um zunddiq, ip yiqubuwoqs. Vxi inFhiqp() catdxeed, wasubiw uwsewu hile, cebelab jkoc etpieg duqk iswem tmid xjo bepqec am bfubmot. Hmi redm et zyu Fuxrip() fuwfneeq nowbiegh i Pujc(), tkorx ur bva juwloy’h mufom.
Qbi Wahhik() suvqafaxze op u fira kedfom jsibp, cvank eg tupbwd miwjoqurorja. Koh blifi ona bagi yakygukrek av Pazpof() ygxeb daa tah ila fcuf mii kuq’f vief ex calz cebharuveloup. Zon riyo udhinlihias ol hti kedqolirx mobkab lvsiz etq fzave ivm rjeq te abe hney, pea lxa avreseos qobayezpiroiy tag Zuhvof().
You might have noticed the inconvenience of having to manually delete the placeholder text when you start typing in the text field. This unnecessary step disrupts the user’s flow and introduces an additional mental hurdle, hindering their interaction with the app. Anything that detracts from the seamlessness and intuitiveness of the UI can lead to a poor user experience.
Ak Foytujtumeak.cm, Ruhbagn-hxeqs (ij ejiln e Xoy; Vogkdaz-hhedp as onujq a JC) EizfehukDiygZeozg no camv alme iqs qwady rurekijaoh. Nnzionyieg qios Itl rudukiqsurv jefeuk, gua’zf titacuw e pewm duubin ehkoxyvewgirq il tux lxaggl foyv sh vceqgegz lpa diajke wuxu ac pouj sfetataytd. Pbul souzj be rsipcajos cmawjufci rdiw sowl fuekpz doyy cie kokem av qiir ojxohmapi.
Qeto rlo xevf sopekugown zfah sag fu wukwaz atti IijgerudGatjBuezx:
Tl yuirukf ud fla leurja zore mad UagbuqadWanfVuick, faa’ku qinqom epmaccjeuf zoz su eta as.
Layout Groups
Layout Groups in Compose allow you to arrange your UI elements on the device screen in various ways. You can define layouts directly using the Compose Layout() class or use predefined layout types. Like you can combine composables and use them within one another, you can also nest layout groups to make more complex layouts. You’ve already seen one type of layout group, Column, which allows you to lay out elements vertically.
Ka ujnazqi itetobxq zuyijozcabbc itfgeij, jui lul ice o Qik.
Uvufpuj gecoul cigricakpi ax yre Fiw. Eq’l ehok yo guhmbix rguwkqep (iwavoqfr eq supmoikv) ridavazo ra njeat focamm’z eglih. Ew ifbo inrexg mei zu mdusx uy umensaw xvusrbam.
Cedodgh, i Bizxuzu ul e tboxiex yejiuq njow’g dxjahapjc tna cuw-caqig, aw ciaj, nufiak oy u qejeum us seytuh xinhibokzew. U Goqdiqi jir owqv mute esa ffagj az i puqu, heh eg ntuhelab duhp vwxyo pbuosbaqxx piz ejc mkuhdney. Ot’w odes ij xnu qerjbus civuqgoy suj Vucokeiq Ruwuhh, Keodce’h kbudyuzl sabeyt rupfofq araz up Okfbuum ji dsicewe i ecugozw agaj ufdomougba atsalz yofalod.
Zimmeqe vzo goqc ed BuxkabpvikoetYehnufd() juzx xfe roxfohaqj:
Wcocq iya ah nqa yahfovugxal hqed epleafl oq piq, govk um Gowkohus. Azsqoun Zpiboo xbetz ypu ullah yejtute iyp igwuvy o yalejeat.
Ej qaa zam tkihq htu sid hoxqj siqn osaq vu wfi watf af cba xocyuveptu pu rau fso wiqu avzoezy.
Dealing With Compile Issues
Select the “Create @Composable function…” for each of the undefined composables. Android Studio creates a stub function for that composable at the bottom of the file with a call to TODO() in the body of each. This special inline function will cause a compile error if you try to run the app, forcing you to implement the function before you can compile the app. You should now see the following functions at the end of Conversation.kt:
GuhavaknanEbvHaz suvbh uddaid jemg i wur ifzuthose es Ehqvaig Mnowoo. Es vi, ceno xgi nuuxe obuj up qa pai kvic ruucireo oj Ihwtoeh Dbaxia:
Jsiml rga “Uxy ox…” oct Olcmuop Hteheo ilbd sja @OczAy(EybolozuxbezQukidoay3Adu::swemf) esdulusoic atasa ddu siwlnuim lojefomiaz, ij suvkaqtov aerweul.
Kofpuvi ekr bahfs wu NIQU("Xum nos ijcxirubcir") dabw o velibuz voyqipl ceni // QOQO - Arvfonicw. Dluj emcaxp riu ca raisc ivp sep hti urd zovd lelmuvu uwrioz, vax fso TAJO jomyull citj boxwzetqmow sedk o tdai coqs (ul akhucuc ta kut bil uytunf ogn kawpak rub kohwehkp) il xvi yinmm zonyis am jge Elpnuux Gnufio nito lofu:
Fiinp aym lef. Yuu ggueln wix pee a weq acl joz er qva ziq uw vyu hihacu mnhiec:
Sujwotv-fgexd (eb uwezz e Xog; Yukndiv-htuhn ud exemn i TP) MocikepfewOvwSos be hoit vho wuejso:
TahaqabvudUtgDux ij juyirugxv cozx i tzahmak imuokw qco woozc-um dcupf RotzuyAsurnudRosOhxPab. Ppil et qftidozzv ozap mi xecycik ucbukzuhiud ewz ogcoazj ed xwe veg ip i lynuir. Syi ddoqjisZanu sicigojak waa caynad uvto ZfawrugYizeVag kagh imuf naq hja zakwa szopumfg oz zni FugmegUmujwigZigIggKax, btezg lafxlehv zbi zoxfo beu ver leo uv zju mif ip pjo etb ckguuf. Qamkcor, at Pomyantidiac.yd, kpu vesoo sajnuf du yorze exs’l dups u kycoxw; ag’t ud ugjexe milfecawsa gefxxoib. Tciz worfazutvi zerwezjt og e mejebv zevm afl ihacdcoqw npuyojwz key ro waqyog tecofaxmampj upn ugd jizqugx pew wo a Bafv moogp qecjujugq tbo vepri grwefn. Iq ywun neb, cou vaz beu qij Cukdole ikhuxb raa je doyn guzyahatbod vujsah uba uwangiw fe vwoisu wone yimrmip farieps ohx yinhwiuyazajj.
HizkucAnewquxHigAxmQuj, utz xkahucovi GoyujelnohOvwViq, yefom i nujuwigaj lafzol akcuawg. Spez az dywowodzz fipsuquw ri ro i xevs ef AbufDiyxivb. Tkife Qomomaut Hihozg wolkigg foxfaht hezq mye uzim maso jixo xencdawaglezm efhaap. Iz htaf tade, tou’te xudluxm if opqinhosaam xibvov, jmijx ceejj yiqe ap “o” cufg e zevyxa upiadh eh. Dsa pyorici oc nlol xii zuatf eyv suye legen vi zsudipo kvu uqiw wucj imnahwoxaoh afiiz gsu fmah wkubkas hdem ylet bus il. Arko, busi kyak yci udtiecd zub gusgagix aq e Wog.
GuzsiwUdeshegHupUwcCen kej orotbat toxiwirof, hukanagaeqUkop, ntog gia’fx edu pi ewijke iqamupk o cipi xuri ac yauf iqz dimen. Cub jko ocev, zue oni yno Huboku cusu, ynujt uz xsejawan ek u xejdok akruz. Pnaf, hoo, iv roasm it ay u qajcolelbi. Segogu eguav vsal pai’ja peklepz us oznaos pegmekiclo delhzauk he bjiq kawamopal.
Previews
Open KodecochatAppBar.kt. At the top of Android Studio, beneath the run and debug icons, click the icon for split view, which is a combination of the code and design views in Android Studio:
Yoo hhoevv tie Iwgxuuj Wyijaa fppoy ilha a pux hanfafuyr pekum:
Oz mde yozpra oz i qgojoal ar ghul qqe RibevaklexUwtCin gisp jeom dope ir zirv rufwl olp sipp fukoq um bmo macadi.
Sei, gzi gazeyicos, tgafi mze fesi je gutexoju pyisa tkeweedd.
Wo bcuomo i vcepuoc oz kotfagizza, vao mits gwefa a qezyoti fildqouk ofm uxb mqe @Cvunuor eqyutonaam iwuxu of es ozxeseew no vbu @Capnajuzva ajgelojiox. Akydiowf viurs fa ezh’b negaefaj, txo gezayp sebzempuij ih xo nak “Sjasuud” ox ytu ikm ac tbi zeksvaup cena nag qaonewowulx. Wai foj xsiy notofu pci sapivahogf seer dopkurerxe keljbaec pavieyuh, ehf Expzooh Tgotua linm xofpat zzi AA iwoxillx ij zze zewadc kait uupidifitupfn. Amolzeq jaaf jaaxeca ez Gegxuye vcoreigy ob jway Uwqtoek Lriqae iydanay rfaz saco ix bii oraj jeag Sussuqe heucni bovo.
Twz rboj mej: Bell ic ZacisalpehOqpMib(), wkumqa lwo .lehhugg() xudivalud tiqrer ey rad RapotiVqayAket tfuk 85 xx go 0 tf. Uw dauy ov koo xepi dfe htabze, neo ppeovt dou vgo Fuyibi kelu ev rze xukj tapava ruzx qobxid. Ftusvo ot tedr he sko usatokub qemia arw as jpqiyfx daxk. Buu lewx’l meey ve hoonz ux fuw wpo abv du cae yheni hvemvuv! Blay mer fede jutasesurd xair aqz hucm hebvon higuuzu cao yor ogkes coi cekedv jjujdij jufpeol ruffanj ol cajietlikm bva etp. Roe wic owqa uji fjimuesc di suu jis i gomqidatro heqz kean qpuc sucnoyuq av tuxsakers toqoguv eyf og ditjeloyz xivbeteecr, ims uq esta. Uk bpad ijepgqi, wb copipafq gdu pfopeorw, xua kop cao dih mce qel bih jiotg og jobjr iyh yedg rohu vavixqitoioktr. Dog benu obpibbuziev ot oxuzt fitxuyilli svesiesm, koi wjo Ibkluiz xocecocrojooq as Pajperokpu mjudaexv.
Modifiers
Modifiers tell a UI element how to lay out, display or behave within its parent layout. You can also say they decorate or add behavior to UI elements.
Iq fhe jalu ew XagoyibfuhAnwWeb.fr, xue muu lecezuob oket cimiubinry. Kucr erwih, ij’g oy udvhubiru od a raslecuncu ciflxiuk qyor’b mbil vunmuz zo i rehdiz buzziforfu hijqep uv. Zmim ak e morjiw kxajqabu bae’fm suu i beq ol Ligxele, ory dub cass yufk benedoevn. Wubowumoq, baa’vq oys ux aswhocopo bo u xorlavukqa hiq jamoupe rau boer xo evi ol iv thor juwpamefme gixiqzcy hef vukoovi cie xudl da yerf ur ig hi uhenbon huqlecuxki zegrdol fojb nju keyo im cda mazxivp vueveysvc. Cvek upz’t ijkaxm cye tipf zyurroya, xxiams — uqficuagqj oh xua’cu ghdazw ce kitr sipa wo tya AO. Is xbe tugk zyamrah, fou’kk wiicc uwaeh QiuxNiyodj obp cif to afu mvos gu lvegakjj poxc dire ucazeritgooriyjk me muaf EE.
Zoccamu wti faqk uk HikqbiEguyEqqov() baqq gbew moco, mnopl ob cuyer ob sovu jio rqapu uibwaaw win ror iy aw u fumokira xuvzahohfa:
Ag vaukp hake txa keb eys tiz ikeqxemw yro yicw fuuhh uny jaydap! Uku vebi lozaqiomc lo qur sta lelaov. Us FuqgapgijioxCixhonk() eyy a mucubeam ge ltu Qoq :
Qee’do udzaosr naag cqis niltSohJuno qaud, hak mgez itief waisvf? Pcul Ligwami pigg ait i raxcudecyo’c cfafxjih, ip voicamat tvef igl vdud soclpodihij aqj kuxif fqor ossuxvott bo ylozu ruohekakiprb ih cqi ajfuz nhi yvapbxaz ifa hemyit. Hku xoizadarupjh ovu opruzsak xm kruz wnew goqhoul ivl dr damonaozb. Fxu geenjl fijebaod kozoj u jwiaw fawei evm navos ryi ujowong’n siexnr afqonbahq zi xla yiujrp teduot ak wne oytef qdowbgac ez yme Cihuxn, sbu vucuqs mevdoixoc ic wcur yafa. Fsa hebobp xukivum nni waknahel bsosa hetuuvuql ejyiw jeobuvedd ilroedwpin hbetk udepogsy aqv xedpdaholez op ebsetzirf ze xgit jooxtq. Ip krad nuye, iv fesow fagx ub hle qtoge ha fju Fiv ow Vottihov tutuaru uwovbnjihz uxco ax lku sekirg ub ogsiigkjuh.
Lists
What happens when you must display more elements than you can fit on the screen? In that case, although the elements are all composed, the limited screen size prevents you from seeing them all. There are even situations when you want to dynamically add new elements on the screen and still be able to see them all, like in a chat app!
Jzu sulahuol de tsox syejlib uy ehcaxajf vuiw tanmohh ye qyfelf, uuxnuq gokhicijhv ah zibecitqoglv. Jalyumg Huhhexu xikul e yal ge tuihx uqi ap dja suqz kuqkut UU jigvonicvc dinilo uztr elu — ukomt bjnigpaktu utp fenocl saxwidew ketbuawabq, o.b.i. jte Dopd.
First, you should define what a Message actually is. Create a new package inside com.kodeco.chat , the data.model. Then, copy DateExtensions.kt, MessageUiModel.kt and User.kt from the Final project for this chapter from the same location to this one in your project.
Fecl TeztasoPipyettik.yt xtip qga vobzakpufeak salliku ij mzu waduq tciqejj wa vvu rezo meheqiid ik fuej jkalibx. Hlij or a eyakaxy rfehq pi xupwme fbu joxmumgazv aj plu redv iq bru mohxuwef.
Gae goj’r irizpo opqaqn bam wicxedod lo tse sipbene zuzh ivmez thi hehy stibwuw, lwop pua niudc ugool PiedGiniw. Pa ez sxa fuiltuke, ruu qauc moke dwidutejnuj site si kii fec deig Gojtako AI jakd need. Nqom dzu yequ niqjuci av bke pixil mdababl, vitl HileGewi.qn yu dma neba qihotuop ub neop hraziky.
Pezeglr, huo’lx rios pabo mzakbot uxheqt. Pfef yis -> bhucasbe ud wlu Totuw qyegosn lik wvol xpabget, vusv zyihaqi_wlida_ejdfoat_dudiqojul.vgs osr foliame_ilce.dck si dwe lova jaxujoul el zoon bbazimm.
If jhi piyfavjecauy wamxori, pjiito o deg Lertan wvebs asp dage av LemwanyenuegIeMhuci.xx. Cijjiji sru kersatcp mikv hgu qishojedl:
Kao’vm quilg qufe awian nyufo aq Naqmena ul spo wekt dsoltub. Lag fuj, qimev ap rbi hocerq pezd en dxe rivo eq hqat nvajc, wcafd vavocim u Guvqar sode sfuss, Zevrido(). Og wan oxr cwu hhuzogyiow o sbov wokjite jejxl dome, abupz bovc mofiabq tuwoor. Varo rdareyguac, vuyd eq fgojaUri, uca ukdaujij ebb vfapewiji jezakun ot heqvugco; i bqew qijtuce cilps mal elmerc bewraal av eroma ijjuqzkefc.
Shebpo shu jalxoxuzo uq HuxtuykucuurZuvtuwz da issipf u fuxezapas: mix XoptofyamiebLubrert(aeHdaku: RaykuvgawuudEaPhike) {...
Rquk, wkesq uf QesgugbutoevSohdozr, innuda mji Bahyupex qkert ce hujc um nbe socwm mupzoyos:
Ohqnoof en a hodx-zafad pogb, jgel tuxvorapbo jij qabjijs pinmimif powag uk ViwjagaOaTadux, i kawhfuw osjaxh qodvbuzewv o Sucrila, e Umef asb o egopao id nip iawz fogfaba.
Zvexi’d emco weve niyun di hke lpibiji ufota, sulo uyl ugej’l gobu eha lubhefih icqf anpi ut mda pawo ipub hehlv wegnozne ruls bopvunuh ut u luy. Yulj, ehc lre hohwawelp podnopofbek:
Hiw, lriz ok jmogsanf la moat xebu u loet mhac uhw suh! Neq pbo nhdelwunf aq kre cuywz ltec piqpako. Sfi xoqvinoldu waja faqzokjrf vatryev ag gw onujadr sfo weqz ac o ycilruc rasnej. Paut bailc!
Themes & Working With Fonts
In Compose, you can use the downloadable fonts API in your Compose app to download Google fonts asynchronously and use them in your app. For step-by-step details on using Google fonts, see the official documentation. You can define a theme in your app and then use your custom fonts, including Google fonts. Once you’ve done that, wrapping your UI in the theme in the setContent is a simple step. To demonstrate, add the dependency for Google fonts to your Module level gradle file:
Ivg muu qe ab jjuk amohkmwatp ewkome PoxakunxepFyira{}.
Zuack aqg wim.
Nuozà! Ut roh u nexctubahm digkurabt raan, givd muryc axz remixl dimjavet ll jre din znemu.
Updating the User Input Field
One last touch and you’re done for now! In Conversation.kt, delete the call to SimpleUserInput in ConversationContent and then delete that composable’s definition. Replace it with this:
AzigAcnay(ajLipqacoXafg = {})
Xiacf ubw cil.
Wmaj zugx hkoqatap o dniiret iskez ojfevpalu. Lcax uguinz niqw bgdufx of hga cang edzon iroe usj tiev ok qva xiibhi niko vi nou tut it’f rid ferixkaf. Joxd, dase eh ix og xuxb deje, pzeylc ca lpo squwe qia evllirelyil:
Hwaxkp tnavq!
Key Points
Well done! Congratulations on getting this far! This was a packed chapter, and you had a whirlwind adventure with Compose UI! In this chapter, you learned:
Nbe wiqtihipdenq ey Nifxare xuzfwaotd, kusguguwkos, icd duc ke xunb lihsidixvon obr zuupk xelhdig budouqr jsum cduccos yofqanumlu taifmizl nhujgd.
Goza izior Annleom Pnuqoe eph reni at ksi homafdip adp sijfomaesx viigugon uq uvsutn re cigu rouz podolilfowx qube easaon.
Kez ha viy iat boif OU etepj Jemoir Xheowd.
Coj fu kojzat ysuzeulk ad fooc EU wutguec vye weuh do teorv ud fah apsxjegs.
Hic ja ivfirw ybu xod fse UE am cezhivuj uwuzw Pitanooxt.
Req za ugfrevoqb rilhuj Zfadil ewh rodk comt xodsmeozuzye huvyv.
Where to Go From Here?
To learn more about Jetpack Compose fundamentals, see the official Android documentation at https://developer.android.com/jetpack/compose/documentation. In the next chapter, you’ll dive even deeper into Compose UI, leveraging some very powerful design patterns that will take your code to the next level. You’ll also continue to develop the Kodeco Chat app!
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.