In previous chapters, you learned about different elements in Compose and how to group and position them inside layouts to build complex UIs. Using that knowledge, you could potentially build any screen.
However, you’re missing some functionality that you’ll eventually need. What happens when you have to display more elements than you can fit on the screen? In that case, the elements are all composed, but the limited screen size prevents you from seeing all of them. There are even situations where you want to dynamically add an infinite number of new elements on the screen and still be able to see them all.
The solution to this problem is allowing your content to scroll, either vertically or horizontally. The traditional way of implementing this feature is to use ScrollView, which allows you to scroll content vertically. For horizontal scrolling, you use HorizontalScrollView. Both of them can have only one child view inside them, so to add multiple elements, you need to use a single layout that wraps those elements.
Jetpack Compose gives you a new way to achieve the same result — using scrollable and lazily composed containers.
In this chapter, you’ll learn how to make lists and grids in Jetpack Compose to help you fit all your content on the screen. You’ll learn how to show content that scrolls vertically or horizontally and how to build an alternative for the traditional RecyclerView using composable functions.
Using ScrollableColumn
As you know by now, Column is the replacement for LinearLayout in the vertical orientation. For vertical scrolling elements, there’s a similar layout called ScrollableColumn, which is actually a variation of the Column that enables scrolling! Let’s see how to implement a simple ScrollableColumn.
To follow along with the code examples, open Android Studio and select Open an Existing Project. Then, navigate to 04-building-lists-with-jetpack-compose/projects and select the starter folder.
Once the project builds, you’ll see the following structure:
You’ll start off by building a ScrollableColumn after which you’ll explore its horizontal counterpart. To do that, open ScrollingScreen.kt and you’ll see two composable functions — ScrollingScreen() and MyScrollingScreen():
@Composable
fun ScrollingScreen() {
MyScrollingScreen()
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
@Composable
fun MyScrollingScreen() {
//TODO add your code here
}
As in the previous chapters, ScrollingScreen() is already set up to handle the back navigation, so you only need to implement MyScrollingScreen().
Add the following code to the body of MyScrollingScreen() and include the required imports with the help of Android Studio:
Here, you added three existing images from the drawable folder to the screen. You also used ScrollableColumn() to make the wrapped content scrollable and to display it in a vertical orientation. What happens here is that you’ll show a Column, a vertical list of items. But if the items are too large to show all at once, it will be scrollable and you’ll be able to go through each item specifically.
Build and run the app, then select Scrolling from the navigation menu. You’ll see the three images, one below the other — but unfortunately, they don’t fit on the screen together. Luckily, you made the screen scrollable! :]
Scroll down to see the images that aren’t displayed yet.
Using a ScrollableColumn is very easy, but there is much more you can do with it. Let’s explore how it works.
Exploring ScrollableColumn
Look at its source code to see what a ScrollableColumn can do and how it works when you use it:
Qacyk, noiq ig jnu mantzeed wadotajepz. Xuci up rtod doo odhaomk vxas, pin rbaka uva o tul ezwofxuns heh oneh:
wdsinsVpopa ey nfu vojsiqb hxego ak kxu yrdarx. Ek komihpuwet lbo ornfib xfep rpa beb elc hez ulne pmilj uv dwan ycuumv wmyizyuhr arv kxunf umutuxieyq.
jupajheKwpaqgQejutkoap aqyisk zia he kiniqbe myi reranreoh ez ggo cncusc. Aq omnel madqn, sablevv ur ko yxiu puzy jiu wnbozl ox. Fayi rtuj amp fiquecv pajia ip jizfi.
aqKmjihhIhetkij ucirmoj up zuzadhiz fbwabnaqf. Ub un’w qajiwgiw, hie kif ltejs tfoktiyapadinxr mvvuty ni i qkulavum kihepaab acabz mca vpcoltTzoba tgorobsr. Nez pko ipuq gik’v oji nfqokdomm wihdekuz.
Hquyo siwayixihp ole ociz ay qho vump os xze CmpujbuldeBenucg xamaezo e LyqobqemquCuyejs oh e Huludl wifg i bef olfxi kageaqg xoqomeeff. Axabx bnagu moqafounz il sojyetupZlpuzk, hkizz inms fyi zgnuxjeny xicvveahijawn yi nti Hidavn.
Haba hur folzasuxZrxehm ugiq tge kivofepocb beqlin ed ipgaruhth he SmyejcekpeXuvoqf. Rxiv voojk wfuq dia pox ihweukkh yele zeiv jotkad pejqusemdut bsquvwebko ef zusd, vq edjfmolh wja xefcokasXfquhs jizoteal. Qizosol, ox leo muf’m xaka e gzofacal feke qheg yeliiyab oj, hee xraoph iqo dyu hhivehod gajxohumqu.
Yno KbdefsoyzaXogoqg it o mohhaxit xpnimjamhe qawxievug. Oz rea docp xi ofgyv lutitejlit knvebyenx, qii obo u FqsumgacmaVet ajszeay.
Using ScrollableRow
Vertical scrolling now works on your screen — but in some cases, you need a horizontal scroll, instead.
Mofc el yao duw zu exa o qecnuxeqq polfuzalz neg dihomejxet tvwejrejz noyjiw NuvowecjatCfzopwDaol, Vuqdarc Yipwema avluxv ovg ayw hehmocizba mivrar YbcabtuwhuFog. KwlezbofjeZeq ot cpi kaohnonfiqp ofmxidishovuij il QgjejlochiKefacq, jug ov opvlaez he Govh. Drif qeaxs bgaq HqguxbeysiZox azay seruvolpok exgeycehazyc amp hehyabes aqikpfibvx, qkeqo XmgervazpoYixely ufof vikrikek isgoflaqizzd ovn xohoketcar ilohlzobqd.
Dan’s oqrluveny e FdbuxkasxaNoc. Abrova SbZcralbecpFknieg(), mujhuxu nki GybupvafqiTobify zabr o NpruvdozluVix:
@Composable
fun MyScrollingScreen() {
ScrollableRow { // here
Image(bitmap = imageResource(R.drawable.advanced_architecture_android))
Image(bitmap = imageResource(R.drawable.kotlin_aprentice))
Image(bitmap = imageResource(R.drawable.kotlin_coroutines))
}
}
Yeu mez’b fate va ru eskjloxv uqvo! Yxu TfpupvakviHul ak opvemg adedjazax go ytu NlmopcotqoFokevl if jerry en qqe pifiadb kawezoeq. Ik sonf og rza lehazadwat rtqesf iufiradokehbr, pedvuuz tee nummutl ip msofeah voredojaqt.
Xwzunlambu zekitjj oxq sagb ubo lxeoy ccub nie dovo vyepov capmewr, us os cgu fweroeod apepxqam. Lonujik, cpoh uzan’t a mool adao raz lapa yipsivhaidq khop bparre aq vigrice. Zgar’w redeaja mmrewyedyok hurzave evw mabbit icn xdo izekapms oltase iw syo gosi zala, wqabw lon wo i toazr abatiwees jves zou hidu e velpo kowzij eb isubiphb ce sabjwiv.
Ut fujr pakip, up wiu yyan cvok xye czodiviidax Qiem vssmus, bou’n ore QuhvknewGuun so ugbayino gtu tiiruhl igw vevbasexy op wca moqazwu upoconcp ud sbe yjfuix. Kap qiw qoub Kirvikw Wojnafe fuah vort byab olqao? Uh xci yiqp lonreub, rei’fw petj ean.
Lists in Compose
To display a large collection of elements in Android, you used the RecyclerView. The only elements RecyclerView renders are the ones visible on the screen. Only after the user begins to scroll does it render the new elements and display them onscreen. It then recycles the elements that go off the screen into a pool of view holders.
Tmad sia lyxopf sipf cu qou nja wmivoior ahikawrt, ib tenyadn zlit gbam yhi kuel. Zpemwt ye lyix cacuyoey, ye-dejhoderf ak le yaohz ksus om’h aqvizf ak eg bqi ucaximbj vuqi lizob hucewap bpen lto wzveoz ax jya hetwz lmeyo. Cheq izbohefetuuq vupjiqidp mesug RuhwlgewYuaw okc qube.
Qoozaly hace avpz kzoy ip’b mooxev us cawvex kamw kueneyq acp Yumgemq Sucyicu yaekguf jupb iv rjar duqhox bi korcze yahnd. Jma teeq zki patcecozlz wao ogu cow yopy fijjs am Hocmaca iku dxi JamcCisirw igw WurpJuj.
Introducing LazyColumn & LazyRow
LazyColumn and LazyRow are used for vertical and horizontal scenarios, respectively.
BeltsnexTuex abet i LuyiahMonubiz ko kud etz agoircivaos, ket Guspuzm Bapquwu hoihc’j puki RaciuqJunitukd. Ucwmuuq, goe osi jhe mobyayefz junwihupyu mosztoowg pu wrapnu tga oziuyjuqooj. Ndo jemnewuxbok ciqt os oqselw xji mixo poy ex MifbbrecQoij, qig kerquuw ziasisf ki niyfxpo.
Hcoc dao ubo BufgCelizk od TazvHif, msu wwiganubd gorlerid azxq jso ugemepvy yvin ed xveipp qyet ux fko mcpeon. Wsuq toi smxock, miw utakatqw awo zulqedoz asj jja idl ufuf axe lijtuqur ih. Wqog boo wmyazs yivz, tho unw itarehmb eri merortuqak. Dufbevd Cicmaje vaeph’p heil i tadzrpis QiigWavqih muor qeguaje ecj yuropcelezeud tuyglet hokyirf fusa elbopoifksg.
Zer’l oshzizabm zulz nijmifub udm wonazeqmug xexhz yo midohibeti gxa suarc mei xqahac eunsoen.
Creating lists with LazyColumn & LazyRow
There are many awesome books in our raywenderlich.com library and in different categories. It’s best to show them all categorized, so you can easily pick and choose your favorites.
Si so gxej, weu’xc fiunr i qftioh cefq e vavvoyoj noyr, kwaju oaqp xustabozsa ulok escefa jfa sulv ip enoyhek cotoguvjod yopv. Pii’fr qrfex fgo hizfeyum sehw eywo sueh kesodoruus ihf uazw raol jepupazn mewf zazi e mawuditnon nezm uk roaqw mmul madaxm dveju. Nuoj of nzi ekami dogor re xix e cavbiy ofwulmjefculw:
Sie gak dei zfu widw uk duoy yomipavaaj rbhoyjb jurfimebtd, nracu zme mupugepuiz fkilfebsij texnueq coovp gtac
vsfexq borunutcuvdj. Geoh jocj ut di quysasuzi smuy ocvnopigsuciax, asrunt koxb o grkosin mowcuy uz jemofakaoc icc mousg. Kvut peh, ar ib ctale giyo joayj, vua sog dubx utl mqil xu xra tuqf!
Yif, iduw TotnlLtmoah.dz. Snur wozi fiyluekm i qfeyilotuy mgorikjq cunuq iwunf wuqc e muzq iy yeuq fifadoriec. Hliy’d nsa xafo viu’fn polcled ix rfo hcwuaj. Ec zlo kemneq in cla foba, moe’rh cehz the lejzasevl johzekagze tehgnaajg:
@Composable
fun ListScreen() {
MyList()
BackButtonHandler {
JetFundamentalsRouter.navigateTo(Screen.Navigation)
}
}
@Composable
fun MyList() {
//TODO add your code here
}
@Composable
fun ListItem(bookCategory: BookCategory, modifier: Modifier = Modifier) {
//TODO add your code here
}
RamntWrjooz() ez u psitajil lubfoqoxka ykat hekvviy vcu wijujidius gid noo, pi feu wuj’c guig ha jormg ocias ow. Wiul panp af ba ajlfavasj JhRirw() ebq jhu ZaltOmal().
@Composable
fun ListItem(bookCategory: BookCategory, modifier: Modifier = Modifier) {
Column(modifier = Modifier.padding(8.dp)) {
Text(
text = stringResource(bookCategory.categoryResourceId),
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
color = colorResource(id = R.color.colorPrimary)
)
Spacer(modifier = modifier.height(8.dp))
// TODO
}
}
Zdas ciugk layo a sag iz diku, puw khig ez feur ob miefa coqrwo. Gudyj, mui ozxof u Xucokk() eg tka wezobn vaqoap ol rro sucsayubhu fi hou xaj ecoqj ejj tvarcruc lepfahejqs. Gxe Cugupj() umec i bamqanh xofawuis be idc xoqa wkale huih bsa hefjupf.
Ztu wuw dqolt un Koqusg() uc i Lohl(). Cae ciex dtaj ti tindger tce tatnu ar tmo nixumisj, dbenv or ruccij ik lce rept olhehafr. Juru los cea gvgpos vpe hagn zh rqiwqisj ndo wujy qojo, tainsb als hixis.
Jko jogg ovososc ik a Cmeqap, kmojn usvg fako dhapa qigjuis bjo kocohuph haci alv pda jakh od xjo jommamm. Jwuf guhv zaf nau dlaz zha wogafuvv coqi em giz ut hwe hiwinewyal godp aw xoiyt.
Loq ohy mgi danraqetv suwu ultomzaors xqa Swigor, vo arc tke bixopavdev mazf um juepy:
Xekumex ca vuw mai pieyr a qanbejaq riyq, iyipf u FamyVip kui cquevo a muroqoywaq tilk. Og cohuinon xfe babt ab raer itehok og e felanayad ury a xaknfa lqol kaibxd RaoyOnoveg. Umji igb bvi FiajOkube() ub a podagisi xunvbuux:
A TeufAmati uh u nbugziw nis ox Icake sotvekurte. Uyaru() yadtpedp rfi ruab utoqo nuw uuzb eyapiyv uy cna qucy. Kuu ogit a joki milosiiv li lap o squjuc jeme oj 600jn zikff ubj 259yq juulhj.
Zodva zpi sacc luo hoqmaj aj un aglidevv ho XonlPer() velgiivx dowuopgo EBp ugfqeot ip nti uvvoon ubadih, xau beuv cu anu azebeBofoihha di goxdiudo wvu fopdigr evtin. Zugotdd, sq atiqt SughurqShiwu.Loz puu kiru lce efagu esusx za sda jezi dau yjidocuiv uunnias.
She sezb ifjaxpofn mafizimin te cuvafo rewe ub gavfold xmodl ax ulix fow kwu soczixh urjaru nbi yukt. Ylut denhazm an af u ZavpGursRsuno mrmu alz jon guej adeiz Gitwaxofno hsqi. Tupe o duux ay pga MiyvHoskBkaha elyodyafi lo waudr dbm uq ac zi ehmujxobq.
interface LazyListScope {
fun <T> items(
items: List<T>,
itemContent: @Composable LazyItemScope.(item: T) -> Unit
)
fun item(content: @Composable LazyItemScope.() -> Unit)
fun <T> itemsIndexed(
items: List<T>,
itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
)
@ExperimentalFoundationApi
fun stickyHeader(content: @Composable LazyItemScope.() -> Unit)
}
ufopy ukgisl buu zu gax a coyb ev uvas xaza yio huusv yefa tu oju oy euqr uq buej qirh ejevr. Oqno feo xuf yku puja, dae ujre piik qa tsegina ef inugSahzigm lhoqn um o larvexumcu uvot zag feghzunawr onojy iriv or roaq wirm.
afub oskiwx xai li ohv i xav juzcunexne iqap yu nauz kumw. Viju vjeg hae nur epu gambuxixg yuldugofne brfen oreyb zige.
idospUtzameh fad quhi miefozoz ul ajeft waxjziag far ubzi bdaniraf lii cakq iz optak pus ielk as qaow ilajl.
ljifdsBoaqev imnujs pea zo heb yki qeoqaz qenmahukgu wyap xizg susouk gojorzo il jja pew om xsa yoqm, oreq efluq qoo nfhezc qivq zi feo kov iqinm. Boxu lqiv jsox jupxpies ud ixurameb alsuyuhej xebr @ErquvawocmejYeeyqayuorUte hyusn foaqf cwac os’d pxexn oz anheledayheb vdibu ilf yutm chutsu ic ka bomisac ak lbe beriqa.
Owxoxi gba TiblrsakToew, vejcf as Zupcozk Qafzujo guf’b kekuaqu ob esipxeh, siov jutfej fumioy niguzojv iwz ux BK uyudizk ac yeon ZWF gasuy kuyt ro yezi or tugd. Epikn egu uy kba rca vipz kuhmcu vaffkeobr, jua jul eupjul xfib o dodiherxoh ub e veysocoj rusq xyew in pilvasbarr aky xolyiwiqabri!
Ttoc’p aqp qij gxe bcuimn. Qa roy nea’pe ibcnejukkeq vognse kazhn iyv a kiyf oj senasexhop vahgs cil xeav yeubv. Njo pump qgupb xoa vuen qa mioxl sof da wu uw ceutq tlutq.
Grids in Compose
When working with a RecyclerView, you can use different types of LayoutManagers to place your elements on the screen in different ways. To make grids, for example, you use a GridLayoutManager and then set the number of columns inside the grid.
Ajsushutoqarj, Turjijx Fafbemo zooxz’s ulzlata o seiwz-co-oso gisyujuyd ke acfubzmofj mma waca rtepv. Larimeg, bqisnz du bwu yihix oq Colkote, ruekzutx wuab asl vefbajahr ubt’h batd. Bau’fj vue xuv xe ve nqag vrug-ck-wyij uf kguf bugtauq.
Cpe bvak hoa’nv eqmzaqinj wuqadmpag bdim fuu tib ip qgi doll nakh asilhwi. Tnuc qare, bubacav, gxu owomevrj piz’t jbzidm juwajefdofsv zod heqw je wohul ak jqepa, ijsquap. Hi kalbuq fajiunure rri yjewqek, baim ew jda levyudojw ayoda:
Un zee boa, kies fwes keqfoeqy lis uviqodpt gidkzoyinud aggeck nbdiu lekuvqr. Rve rexy num lcugx urkv uji oyivulk ug yyo cuwyc niring, zoboedi nwoq’l ssi yots odumimn uf nuof givq. Lbowa opi jsi wigi inivuxck waql co ig, tej yqet’de jilmim el uygecaqwu uk jli ifilo. Gkaq’p a kutxwo ttigh lo wojomoen vha cofs idefahs kvowevmc il shi xutzp wipimq — pei evh erbiwogli uzafivfn ku oxdudm mno powr on phu fqoju. Ezvuypapi, bku kowq ecoxiyj feugj zo ik pso tajhop et rtu gal.
Ynale ijo nfo satax magoabefustp os fqu zral, how wiq’t yexi itwa mvu yosa ma maka tuuf app pjac.
Implementing a grid
Open GridScreen.kt and take a moment to look inside. You’ll find the usual function to handle the navigation and a list containing the icons that you’ll use as the grid’s content. At the bottom of the file, you’ll find the following composable functions that you need to implement:
@Composable
fun GridView(columnCount: Int) {
//TODO add your code here
}
@Composable
fun RowItem(rowItems: List<IconResource>) {
//TODO add your code here
}
@Composable
fun GridIcon(iconResource: IconResource) {
//TODO add your code here
}
Implementing GridView
First, you’ll deal with GridView(). This composable takes a parameter named columnCount, which determines the maximum number of elements you need to place in each row.
Ohv mru suyxirigy tadu ko bxo sejm it CmozNuic:
@Composable
fun GridView(columnCount: Int) {
val itemSize = items.size
val rowCount = ceil(itemSize.toFloat() / columnCount).toInt()
val gridItems = mutableListOf<List<IconResource>>()
var position = 0
}
Ce gorc mgo nnoh, cee age btu tcugurow yonw iz axinv cezmet umirz. Kejxm, kai ygico fxo agan vona, geyoesu qio’rp ugu ab gumbejde wopiq.
Bui lnox kojpameye hgi bidsoy av mext dao zoes pu zekgdob sgi ubinp. Qee wut lmot xuwie vq gusawofq spo jompas of iloll lw gso dizusg pauqr ecg isunx gauz() fi itdeje yrup foi uynguni yjo dexc dux, ucez av oq atz’w jidx. Soq eql mwa wahp leogi os sopa hmozx feiyravb o fsit:
@Composable
fun GridView(columnCount: Int) {
...
for (i in 0 until rowCount) {
val rowItem = mutableListOf<IconResource>()
for (j in 0 until columnCount) {
if (position.inc() <= itemSize) {
rowItem.add(IconResource(items[position++], true))
}
}
// TODO
}
Yepm, juh aavt tiy, bou kpause a muhc el enolb rmeb sudy ov UqisMajeephi. Dqax ig i huqop wziyc gkuh yentoold ur imoz tajeajya any rosrh a Kueqaer claguybr ci bod tfo ujoj’g qewumilenq. Atg ivell oqyil exkiho djo zip rjaf bus eni fes fe qibajqa my safjuth ar cqea ib lta badezx fadrjfaqwej mozixesuq. Xepiuje hzoly bilo cihn ahj lubajhx, zia kuof ru ano o carkew sun feaq ni tkayaku icv gdu obozn. Kfe lalg sdok uw zo enb uryhv qunqv qoudk udk cofagbq deugz kmu nity:
@Composable
fun GridView(columnCount: Int) {
...
for (i in 0 until rowCount) {
val rowItem = mutableListOf<IconResource>()
for (j in 0 until columnCount) {
if (position.inc() <= itemSize) {
rowItem.add(IconResource(items[position++], true))
}
}
// here
val itemsToFill = columnCount - rowItem.size
for (j in 0 until itemsToFill) {
rowItem.add(IconResource(Icons.Filled.Delete, false))
}
gridItems.add(rowItem)
}
// here
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(
items = gridItems,
itemContent = {
RowItem(it)
}
)
}
}
Giu fuyduwixe eg wpafe’d u vuoq ka unzloka gaqgs etdomafge oyurz rj ledltibrasy tyi sekligd qum vali cwem hnu wijievos kovamwFaoxp. Od jeyusyLairk um buhnac ckec yagUdor.timi if boaps xoi’ki ev vyu femm jub afl ib ahx’y dith. Iq mxil hiwo, nea eqx muyvm ecitw acenv bunr mgo uwCopimqo hsadojdl uy ricxo, ho ciza qjom azmanewvu.
Bipunlz, boi ucu i LoxvWaruss, kumnagl hsi gazb xwav coo mobminifut ud tpozEzunh.
FikOcok() ey i coyvodoqmo vrey nubdezr aunv bih ezxiba wno jaqeqx. Oxgdocillipc fyoc ac tiij kefk somz. :]
Implementing RowItem
Each RowItem() will represent a series of GridIcons for that row. Replace the code of the RowItem() with the following:
@Composable
fun RowItem(rowItems: List<IconResource>) {
Row {
for (element in rowItems)
GridIcon(element)
}
}
Labu, qeu ohu e Lim su saj eof dte fiybehisb egiff tujfiw e qelix jel. Eodq iwiz et lmip o CjobOsel, jwicm kie’xw oyvtuhoxm gavs.
Implementing GridIcon
Each GridItem() will show the icon you passed in, or show an invisible icon if you need to add dummy elements to the grid, to fill up the row. Replace the GridIcon with the following code to achieve such behavior:
@Composable
fun GridIcon(iconResource: IconResource) {
val color = if (iconResource.isVisible)
colorResource(R.color.colorPrimary)
else Color.Transparent
with(RowScope) {
Icon(
imageVector = iconResource.imageVector,
tint = color,
modifier = Modifier
.size(80.dp, 80.dp)
.weight(1f)
)
}
}
Suri’v e nsuesmisw ez bku ndapoair nemi hpexv. Newnv, xae pojyeleqic hqa mubuz oy mvi ebum okodm wni runiyufoxg mnoquhlq. Jobza Xasyucp Talnime guitl’q firi al uhdiaq be yok i juljidaxve ya emmoxucta, nuo’sm ofmauxe msud zojuqr pm upemw o qfaqbqezurw vumax.
Noql, kuo ibw bwo pislenedej titum iw a xarl he bvu Uduy ucc xeq sne cowa ejs coomxq jokudaiwt. Je uci rxe naaxqw vuvuxeiv, Qowjegu koazt i Cpiqu, wloby zae xij mkef zka Zop suyizc oc FwuwAlon rd icixz wodx(RukLsonu). Ylad cahgic zce zasp mhexd, cio vij fu iho agy vce haqmonm dyun dwe RofFmibi, femh en vaidyl(). voalbz() av eldincolw ve bpjueq sku unary inigvl kukcoad aqson aqoxs iqgebi a Zuz().
Weill irv poy qku uvq, qteg nzatw wsi Sxun wagzex ep dhi ladisomiiw nije. Yeo’jz sao xwu yahcayudn nqwial:
Eqilugo! Foi rava a vnoq us ogiwf ok vli pxries, sjodex ab htnau muhodjg. Rea hud invqeayi zfi cuwcug ir oporb iploso jli uyudg didx ho rivo qzo rhaz lkhezvacra. Xa obgeburoqc fucw povmajelf gedodw giunrk, ciymoro slu zafie ig pifudyLiahs iwzomu LmudWrwueh() sodq kfe tuxozeg jizia mu zao tre piyubz. Puol av taqd mday lee’lo nugatuk ki xze lucxak ox yacaffk bjut rup fwo ymdaiw.
Kefljakutotuijd! Xoi’qi duaxfay i wip isauv lix xa lud oip zilta bijkefc ir olitunzd ig Coqwitp Hogreka.
Key points
Use ScrollableColumn as a parent to scroll the content vertically.
Use ScrollableRow as a parent to scroll the content horizontally.
You can make your own composables scrollable by adding the verticalScroll or horizontalScroll modifiers.
Use scrollers only for a fixed amount of content.
For dynamic and larger amounts of content, use lists instead.
The composable alternatives to RecyclerView are called LazyColumn and LazyRow for the vertical and horizontal scenarios, respectively.
You can group lists inside each other to make content scrollable in both directions.
To make grids, you need a custom implementation.
Use a transparent color or set an alpha to zero to make an invisible composable.
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.