Newsletter Issue #94

Published: 2021-12-07

1.1.0-beta04 shipped, with more improvements!

We also celebrate the 1.0 release of Compose Multiplatform, learn how to leverage slot-based APIs, and see a Wear OS-based instrument tuner. We examine a cross-platform state management library, and I grumble about font padding.

Beta Breakdown

Reviewing the release notes for the latest Jetpack Compose update!

1.1.0-beta04 is available now, with Kotlin 1.6.0 support!

Beyond that, we got:

  • Some new Lint warnings about mixing mutable states and mutable collections

  • Support for mouse wheel events

  • Magnifier support when dragging the cursor or selection handles in text entry fields

  • A variety of bug fixes

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Do I Pass Part of a Modifier?

When extracting reusable composables, you sometimes need to determine how best to split up the modifiers, between ones defined inside the reusable composable and ones defined outside. The best solution for that is to have the reusable composable accept a Modifier as input, as we see in this week’s highlighted Stack Overflow question.

How Do We Remember Across Configuration Changes?

TL;DR: rememberSaveable() of hoisted state can be your friend, as we see in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Compose Multiplatform 1.0 is going live!

JetBrains is declaring Compose Multiplatform — comprised of Compose for Desktop and Compose for Web — is stable, with a 1.0 release. There is also an announcement video as well. Congratulations to all who worked on this!

Video: Jetpack Compose in Square Workflow

Google’s Zach Klippenstein joined an Android Dev Hangout for a discussion of Square’s Workflow library and how it interoperates with Compose and Compose UI. Zach also published slides for his talk.

Effectively using slots in Jetpack Compose

One complaint among Compose UI developers is the depth of nested calls, leading to passing lots of values down many layers in a call hierarchy (think: hoisted states). Kiran Rao writes about slots — composables as parameters to other composables — and how some careful code refactoring can help to minimize how many distinct values need to be passed and how deep in the hierarchy they need to go.

Getting started with testing Jetpack Compose

Moataz Nabil gives us a tour of the basics of testing composables in isolation, using createAndroidComposeRule() and its Espresso-esque API for identifying nodes in the composition and asserting their state.

Medium: Scrollable Grid View With Jetpack Compose

Kennay Kermani points out a notable limitation in LazyVerticalGrid(): it cannot be used inside of another vertically-scrolling container. Kennay’s workaround is to switch to Accompanist’s FlowRow() composable to replace the grid, as FlowRow() can be placed in a vertically-scrolling container.

Medium: Jetpack Compose State Guideline

Takahiro Menju gives us an overview of state management, including what you need to remember() about using mutableStateOf(), how state hoisting works, the risks in having composition state in a ViewModel, and more!

Compose + Wear OS: Chromatic Tuner

Arildo Borges Jr. creates a Wear OS app that serves as a chromatic tuner, by identifying the nearest musical note to the sound being played and how far off from the proper value it is. Arildo combines Compose for Wear with Tarsos DSP, the latter providing the signal processing needed to identify the pitch of the current sound, so it can be compared to expected values.

How to Create a Collapsible Bottom Navigation Bar using Jetpack Compose

Antony Gitau explores bottom navigation in Compose UI, with a particular emphasis on tying the bottom navigation bar to overall scroll events, to hide and show it as needed.

Resource Roundup

100% pure code!

GitHub: dmdevgo / Premo

Dmitriy Gorbunov created a Kotlin/Multiplatform library with a shared state-holding system for Compose UI and SwiftUI. Interestingly, it uses the Presentation Model pattern, not often seen in current MV* architecture discussions.

GitHub: ceribe / compose-overflow-menu

GitHub user ceribe brings us an implementation of a toolbar with overflow capability. You provide the roster of action items, and the OverflowMenu() shows the ones that fit and sets up a classic overview drop-down menu for the rest.

GitHub: TalhaFaki / ComposableSweetToast

Talha Fakıoğlu created a small library for some toast-like popups, with color coding for different roles, such as success versus error.

…And One More Thing

“Fit and finish” will be a challenge in Compose UI for a while. You can create fine user interfaces with current Compose UI. However, precisely matching supplied designs can still be a problem.

For example, this Kotlinlang #compose Slack thread, looks at the issue of vertically centering text, in this case inside of a “chip”-style element. The chip was implemented using a Text(), wrapped by a Surface(), and the text was not centering vertically. While a variety of other implementations were proposed in the thread, in the end, the problem is one that the View system solved a long time ago: font padding.

Fonts can have intrinsic padding, and that padding may not be the same on all sides, particularly on the top and bottom. Font files describe that padding, and by default, the padding is taken into account. However, consumers of the font that honor the padding may result in this sort of centering problem, if the top and bottom padding is not even. For example, if the top padding is too large, the text will appear to be shoved downward within the available space of the container. For a transparent container, this is not an issue; for a bounded container, like a chip or button, this may be more obvious. This is exacerbated by Android’s handling of fallback fonts, apparently.

With a TextView, we have the option of opting out of font padding via android:includeFontPadding="false". However, right now, there is no equivalent of this in Compose UI.

As this issue comment points out, for custom fonts, you could modify the font itself. Otherwise, until then, we are stuck waiting on a Text() fix.

Eventually, issues like this one will be addressed. But it is likely that this is just one of many “long tail” UI glitches that we will need to work around.