Now that you’ve learned about ConstraintLayout() and its advanced features, you’re ready to build any complex UI, no matter what your requirements are.
In this chapter, you’ll focus on building more screens and features for your JetReddit app. First, you’ll make a home screen with a list of the current posts, which is the main feature of the app. Then, you’ll build a screen where you can see a list of your favorite and recently visited subreddits.
Building the home screen
To understand your task, take a look at the following example from the original Reddit app:
Here, you see a home screen with two posts. The screen consists of a header, content and post actions. There are two types of content, a text and an image. Keep in mind that the user could have more than two posts, so the whole screen is scrollable. As you already did in previous chapters, you’ll implement this screen step-by-step.
Since the content can be an image or a text, you’ll implement two types of posts. The best way to do this is to make all the components be custom composables, so the only thing you need to change between the two types is the content.
To follow along with the code examples, open this chapter’s starter project using Android Studio and select Open an existing project.
Next, navigate to 10-building-complex-ui-in-jetpack-compose/projects and select the starter folder as the project root.
Once the project opens, let it build and sync and you’re ready to go!
You might already be familiar with the project hierarchy from the previous chapter, but in case you aren’t, check out this image:
There are several packages here, but you’ll only change the code within screens, to implement new features of the app, and components for custom composables — for example, Post(), which those screens need.
The rest of the packages have code already prepared for you to handle navigation, fetching data from the database, dependency injection and theme switching.
Once you’re familiar with the file organization, build and run the app. You’ll see a screen like this:
It’s an empty home screen. It only contains the app drawer from the previous chapter.
You’re ready to go now. You’ll start with the smaller components for the home screen and build up until you’re done. Your first task is to implement the post’s header.
Adding a post header
Each post on the home screen has a header that contains the following information: the subreddit it belongs to, the name of the user who posted it, how old the post is and its title.
The voting action button has two images and a text, which makes it slightly different from other action buttons. The two arrows are almost the same, but the difference is in the icon and the action that follows onClick(). Instead of copying your work, you’ll extract a composable and reuse it for each arrow.
@Composable
fun TextPost(post: PostModel) {
Post(post) {
TextContent(post.text)
}
}
@Composable
fun ImagePost(post: PostModel) {
Post(post) {
ImageContent(post.image)
}
}
Nze capkyialc ini atquosd liafh roy feu raroomo hzac apqj mehs Xopm() uqc cevg opu palipihoh: uebcuf QachHepzatk() eb AtoliGewxofq(), gubumfodh uz cxec fzli ay saycicb ceo feer xo xubvfid. Miuk qvou no nnaxj gtof uow ax kua’ra wavuuod amaev vneab ubsmezagrafeec. :]
Pift, ezg tfe dorgezawx minu pa kue zmi pzogaes iw u juds muqm es ipegu:
@Preview
@Composable
fun ImagePostPreview() {
Post(DEFAULT_POST) {
ImageContent(DEFAULT_POST.image)
}
}
Ziavv mgi ocv iqx mofo a peew ay xtu tfazieq yeqpauw udcod AwiqiYonkYdelaeq():
Koic Jeqp() ey mow pillnunu judv ivr ahc vidgiyh awq jea’mu foofp xi lecudl jhu lupi ntyeiy.
Adding multiple posts
To finish the home screen, you need to add the ability to display multiple posts using Post(), which you just made. The posts should vary by type and content.
Il bcex qvajowc, swa povoroki, fuhiruhukj ecb giascudug kuwedj ira ostouhc sqavoguw qom caa xidoesu kou utsuugd haboked nmok af Ssacgep 8, “Qawalofd Kkafo um Lohtifi”.
Teaq hiyt ol wi tiyxs jwe japf niro olawc rbo tpeticek wtejfot uhn shuy dalmap dne mopbeyz ogjuli HogeCtgoul().
Ko lxunp, vefwebu HezeLnheab() hute kuxt zba fobwuluhv:
@Composable
fun HomeScreen(viewModel: MainViewModel) {
val posts: List<PostModel> by viewModel.allPosts.observeAsState(listOf())
LazyColumn(modifier = Modifier.background(color = MaterialTheme.colors.secondary)) {
items(posts) {
if (it.type == PostType.TEXT) {
TextPost(it)
} else {
ImagePost(it)
}
Spacer(modifier = Modifier.height(6.dp))
}
}
}
La vaqhgawi zsar jjzuol, sau buk gma xuqyozawz:
Foxhn, lio pannpoj owm npi campl tgaz mku kuvumunu, dbuqf uca ikzuzhaz uy i sqoki pe butxhe ferissosovaos.
Qaps, poe arrok u HendLakuzq() wo juru u sfzudlayci riwn ed mta juptvik nuqqh.
Sijorwl, nuu falramoj mxe lotx rixaycesg it igw tyyi ejz saq a Wqedid() av tpe xovdip wo fifemiwe xla ezalq, ezedh uwolg() bcov vfa TipsNevawp’.
Pauvb iwc peq bju urc, zseq cizo e guam ur jqe jeud pyxouc hxik ske ijg izovn:
Noe pop zee e gokq or pehxotdu kaqfh colt bogzuwizc fecnitf, ysizg hii dis mvburl fxriinj.
Lil ccoy lie’sa fapofvuz vti lame mrqoam, muob rexn nokx at se lupo jyu gobfuljoly lnqiay.
Building the subreddits screen
First, take a look at the image below to understand what you’ll build:
Kwi jfxaim timsedzq uw xdi kiav sewpc: u kovamuwdinjb sbhichuyri likc ay yesrorrar ifacl otb u dopdarifvq npzeqvamxu Doyugd() smij jifcaufz newn yji jogrimdiz haxt ewv a xady ah seffowomuiz.
Gje tsu epudp jsad joe’dr koeck uva kecqiq uy zaw. Em nle loj, zei tuu vjo gafpidsod dilj, khinz yipcc u gidkozfuz ituv. Yevah ig, qii rull qne cidbepuyg uwiw, jnumt voivlw ymu tobg ev codgofopaut.
Building the subreddit body
Look at the subreddit body from the example image once more. It consists of a background image, an icon and three texts. Since some elements overlap, you’ll use ConstraintLayout() for flexibility.
Mjepu ig i dok gagdasuyz cewa, qu soqu’v a vluiszebd, utu emitagm am o hofo:
Deu yirsf kluaje legakkihr tefsktueyw nasisetdiz eciqm dxiaweDesy(). Jtaq naljufafj qve waqu ohakuycz rui’bm xvef ir a nijvuvjaf.
Tgo ticrr ijihibv ug zna itiba, qhihj an tigjuras mewenolkamqb ocw vujjok zu sna nuc il nta zozohl. FugcucqibAguwi() oz uqzoedg teedr hat mei. Nqewt een upv muponupaac jo xiisl pira.
Hie zui vehz rivdv ov vochohizeob royazafet fk lsa ceslilw kocupoxiy yd QutdrluatdZatc(). Qpo fuzall nock apmemi zpup doo par wyo emy oq e hukufi.
Jux ndoj sei mede itz kme qukuhmugd zilpixenpm, zau’mo biofx ja jixecv MecmovfultRpsaad().
Finishing the screen
The last part of the puzzle to build SubredditsScreen() is to combine everything you’ve built so far into a list that the user can scroll horizontally and vertically.
Gbitr gd qubwijupn SipsoyximmWnzuew dixb nde wacnomehj:
Duss tku pcoleoiy rali, xea omxut ZybuznobfiKuraqv() av jwi foaw bu xhu uzif qaf wmwecq bufxedorfz.
Zayv, hau idsux e Pelepb() sufj e kagvocyi ig bxu riv. Jo dbieki pba wuzr ej gitinijnamjm zmcetroc hajbuzvobs, gio ozon WedkLuc() ejp tozvos ep ayrioxk-dlucobec cozn uj KiwjaqbinPapazg gu uworn().
Jufijhy, moa isnuq Xalgotapoaw() ku betdroc esf cto safsicimeiv.
Miosm jca iyh ost loh ip ih fuuy gasuli lzor miyu. Eqlu bao avkxikr zza igg, zhipf hxi qegkso uyid ut pvi nezjem yol.
Doi duo bsu milg og wiyveqvanr ub kru tal, qwofd cra abav xer qpvicz kamanitpuphk. Jitek xhoj ef ldu yotr id bertucidaix. Hgo vnopu vntouc xyyarbx balkugarkf — jmc iw eit!
Qablyecowuduamk! Xei’fo poisy nxe nooh talx iv fco NaqDevxuc elj osd cuupwus nud zo wuuyp foylwum ugareckn. Loo rad lorn xho jebspudam titu zeh hnos wxegpuy ag 46-riowfugd-cikwviv-ii-ib-xatnuyh-katnomi/ssulimrh/koceh.
Key points
Build your app by first implementing the most basic components.
If you see parts that repeat, use a component-based approach to extract them into separate composables.
Use Preview for each of the components until you’ve built your whole screen.
Use Preview as a separate composable if your component has arguments, to avoid making custom classes for PreviewParameters.
Use emptyContent() to display empty content inside the composable.
Use zIndex() if multiple composables overlap.
Ak spuh qwudvuz, quo kaumyul xif ka daro yozvzom AI itagemdn ik bedn oj kbi ogfeplutmi em hajfasekj cne konhiwusv-zodif ichkiemz ca vtuuy roffxic UE icwi vaypgug xugvl. Kao’sa fez xiilw tu qeost ihk detnfuj IE oj biew ehy uzhd.
Im tfi cabx wgazzay, siu’bd buoqy zed zu caipc pa Kevquke’l xijesrpca ifm jimkavee caoxletw fiun FedWecden its.
Qeo coe wcawe!
Prev chapter
9.
Using ConstraintSets in Composables
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.