jetc.dev Newsletter Issue #76

Published: 2021-08-03

1.0.0 stable is here! 🎉

In addition to the announcement post and associated video, Google also published a high-level roadmap for where things will go.

Let me be the 39,304’th person to congratulate the entire Compose team for all their hard work on getting the inaugural edition of Compose out!

However, it looks like the first 1.1.0 alpha is coming soon, so apparently the team does not get to rest. And, neither do newsletter authors!

This week, we see what Twitter is doing with Compose, and we take a couple of peeks at text rendering options. A pair of library authors explain why they did what they did. We play around with bottom sheets, and I pass along Rebecca Franks’ warning that Compose may not behave quite the same on all Android OS versions.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Peeking Based on Sheet Content

Sometimes, we want to have the peek height of a BottomSheetScaffold() be based on the size of the content that the bottom sheet will show. Using the onGloballyPositioned() modifier is one approach for handling this, as we see in this week’s highlighted Stack Overflow question.

Authentication and Navigation

A fairly common pattern in an Android app is to have a few screens be available generally, but have the rest require authentication. And, if that authentication times out after a while, you might find yourself needing to re-route the user to a login UI from an arbitrary spot in the app. Figuring out how to do this with as little code duplication as possible is the subject of this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Video: Android UIs at Scale

Nacho LĂłpez delivered a presentation at the 360AnDev 2021 conference, looking at the adoption of Compose UI at Twitter and how it related to a previous framework they created (Weaver), with a particular emphasis on architecture patterns.

A Vocabulary of Jetpack Compose Terms

If you are new to Compose, first, đź‘‹. Then, you might want to read this post from Pamela Hill, outlining some of the key concepts and phrases that you will run into as you start trying to absorb Compose.

Jetpack Compose: Styling Text

Alex Zhukovich is back, this time looking at the various options for the Text() composable, including AnnotatedString and its various style options.

Composing composable in the Text line with InlineTextContent in Jetpack Compose

Continuing on the theme of text, Shreyas Patil explores the appendInlineContent() option for AnnotatedString.Builder, showing how you can blend arbitrary composables into your rendered text, rather than dividing the text and placing pieces around the composables.

Medium: Loading images for Jetpack Compose using Glide, Coil, and Fresco

Jaewoong Eum is back! Jaewoong is the creator of the Landscapist image-loading library. In this post, Jaewoong explains the reasons for creating the library and how to use it for getting network-supplied images into your composables, including applying animated effects like shimmers and reveals.

Medium: MapView for Jetpack Compose

Similarly, Peter Laurence created the MapCompose library for rendering a tile-based map, with panning and pinch-to-zoom. Peter’s post explains where this library came from and how to integrate it into your app, including supplying tile sources, placing pins and paths, and more!

A Story About Composable BottomSheet

Ilker Aslan ran into a problem with BottomSheetScaffold(): the bottom sheet that it displays is not modal, blocking input to the rest of the UI. In this post, Ilker explains the process required to find a way to set up a modal BottomSheetScaffold(), borrowing bits of internal Compose UI code to pull off the desired effect.

Resource Roundup

100% pure code!

GitHub: halilozercan / compose-richtext/

Halil Ozercan has taken over the compose-richtext family of libraries from Zach Klippenstein. As you can see in the main documentation site, the libraries include everything from Markdown parsing and printing to a PowerPoint-style slideshow composable.

GitHub: ShivamKumarJha / supaflix

Shivam Kumar Jha set up a streaming video player using ExoPlayer wrapped in a Compose UI. Along the way, Shivam used a dizzying array of Jetpack libraries, including Hilt and Room.

…And One More Thing

One of the touted claims of Jetpack Compose is that it is “unbundled”. This means that it comes in the form of versioned libraries that we add to our apps. This is in contrast to most of the widgets in the classic View system, which are framework classes and are part of the firmware. Framework classes are necessary, but we do not control them. In particular, we cannot upgrade them, so there may be variations in behavior between OS versions. And manufacturers can mess with them, so there may be variations in behavior between device models.

Being unbundled means that we control what versions of Compose that we use and that we can upgrade on our own timetable.

But, as Rebecca Franks pointed out in a Twitter thread last year, there are limits. In the end, everything winds up hitting some sort of framework class. And for Compose UI, the key one is Canvas.

Canvas is Android’s 2D drawing API. It is backed by Skia. However, Canvas and Skia do change over time.

This means that you may still run into hiccups, where the same composable renders differently on different devices. I would expect fewer manufacturer-specific hacks here, but older devices may have Canvas bugs that were fixed in later versions. Plus, Canvas and Skia simply change, and those changes can have impacts on whatever uses them, such as Compose UI. Rebecca’s thread has some examples of distinctly different rendering behavior based on API level.

With luck, for stock composables, a lot of these variations have been addressed, so we get consistent behavior. However, whenever you rely on luck, there is a chance that your luck will run out. Things get worse if you are using the Canvas() composable directly, which will be a reasonably popular approach for creating “from scratch” custom composables.

While overall we should get a more consistent UI with Compose across devices and versions, that is not a guarantee, and testing will still be needed.

(hat tip to Seb Roggi for retweeting Rebecca’s thread)