Newsletter Issue #110

Published: 2022-04-05

This week, we look at composables that return stuff and disabling trees of composables. We look at Figma, consider localization, and wonder why my letters are sticky. We examine a lazy staggered grid and square radio buttons. Plus, I wonder how we are going to get from our current Compose UI platforms to the next, and the next, and the next.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Do We Reference Theme Colors From Outside a Composable?

Sometimes, you might want to refer to MaterialTheme colors from some context that appears as though you cannot use @Composable functions… such as a function that would return a value. A @Composable function can return a value, though, as we see in this week’s highlighted Stack Overflow question.

How Do We Disable Child Composables?

Perhaps you have a screen, or a portion of one, where all the form UI elements should be disabled. The challenge is that those composables tend to take the is-disabled state as a parameter, rather than relying on a CompositionLocal, so how do we handle a whole tree’s worth at once? See a few options in this week’s highlighted Kotlinlang #compose Slack thread!

Composable Commentary

Posts, videos, and other new information related to Jetpack Compose!

Video: Architecture: Handling UI Events (MAD Skills)

Google’s Manuel Vivo looks at propagating data from a viewmodel into a UI, and propagating user input from a UI. While the focus is mostly on states and events, Manuel uses Compose UI for the UI in question.

Android and Figma Typography and how to achieve 100% fidelity

Figma is a popular design tool, but how it describes text and how Android implements text are not a precise match. Can Yumusak looks at how to convert Figma specifications into proper Text() composables. In Compose UI 1.1.x, this is painful, but Can also points out improvements that are coming in Compose UI 1.2.0.

Medium: Jetpack Compose: Backdrop Component

Chen Zhang explores how to have a bottom sheet expand over a “backdrop” layer of content, using BackdropScaffold().

Medium: Creating a sticky letter list in Jetpack Compose

Francesc Vilarino Guell returns, this time looking at sticky content with LazyColumn(). In this case, rather than a sticky header, Francesc looks at implementing a peer column to the main content that contains initials, where the “current” initial remains sticky at the top and the rest scrolls with the content.

Medium: Type Save Navigation With Jetpack Compose Destinations

Yanneck Reiß reviews Rafael Costa’s Compose Destinations library as an alternative to using Navigation for Compose on its own.

Medium: Jetpack Compose Side Effects — LaunchedEffect With Example

Emre Memil looks at LaunchedEffect(), explaining where and how we use it, and what happens when we fail to use it where it is needed.

Medium: Progress Animations in Jetpack Compose with examples

Hardik P explores a common situation with mobile apps: the need for progress animations while something (often network I/O) proceeds. Hardik implements four different progress animations, both for direct use and as a demonstration of how you can build your own!

Medium: Dynamic Localization on Android

Naing Aung Luu looks at how we can skip Android’s string resources and use a JSON-based approach to providing translations of string. Naing’s argument is that this is more flexible, as translations can be loaded from anywhere, including from a Web server.

Resource Roundup

100% pure code!

GitHub: savvasdalkitsis / lazy-staggered-grid

Savvas Dalkitsis assembled a basic LazyStaggeredGrid() implementation, using a set of LazyColumn() composables with synchronized scrolling. Savvas explains more about it in this Medium post.

GitHub: togisoft / jetpack_compose_country_code_picker

Tolga Caglayan created a TogiCountryCodePicker() composable designed to help with phone number entry.

Gist: unaisulhadi / SquareRadioButton.kt

Unaisul Hadi put together a SquareRadioButton() that “does what it says on the tin”: it offers a square radio button. See this tweet to see what it looks like!

…And One More Thing

Compose for Android. Compose for Desktop. Compose for Web. Maybe Compose for iOS.

What comes next? It might be for some UI system that is under development or does not exist yet.

If you were building a product that, for one reason or another, needed a bespoke UI system, you might want to consider adopting some existing cross-platform framework. Yes, you could try to convince people to write directly to your own UI system, and some undoubtedly will do just that.

However, as the owner of the Los Angeles Clippers once pointed out, what matters for platforms are “developers, developers, developers”. You may want to try to meet some of those developers half-way and use Compose for your UI system.

But, how do you do that?

On the one hand, we have several examples. In addition to the ones mentioned above, there are Glance (a.k.a., Compose for App Widgets and Wear OS Tiles) and Jake Wharton’s Mosaic (a.k.a., Compose for Consoles). However, those two are for more limited scenarios, and the primary Compose-for-UI targets are massive.

Right now, a lot of the “how do we apply Compose to a UI system” knowledge is in the heads of various Google and JetBrains engineers. For Compose’s longevity, though, eventually that knowledge needs to be written down somewhere. This is not to say that it needs to be converted into some “turnkey” solution, but the ecosystem is going to need something. A high- or mid-level overview of how to build a Glance/Mosaic system and what the requirements are for adapting the Skia/Skiko-based canvas system would be huge wins for future platforms. It also would be good for maintaining current platforms, as those Google/JetBrains engineers eventually will stop working on Compose, and we need to transition to new maintainers.

Admittedly, this is an imperfect solution. Compose also requires Kotlin, and not every new UI platform will be based on an existing Kotlin target (JVM, JavaScript, LLVM). So, perhaps my pipe dream is just that: a dream. But, figuring out an “on ramp” for future platforms seems like it is a worthwhile dream to consider.