jetc.dev Newsletter Issue #113

Published: 2022-04-26

This week, we look at 1.2.0-alpha08, custom modifiers, and composable sizing. We explore writing Compose tests, both for their own merits and for collecting screenshots. We peek at a tree widget and an event queue implementation. And I point out that “oh, just copy the composable and change it to meet your needs!” does not always work out.

Alpha Analysis

Reviewing the release notes for the latest Jetpack Compose update!

1.2.0-alpha08 came out, with support for Kotlin 1.6.20! 🎉

In addition, the new alpha:

  • Makes some adjustments to the tracing APIs, including restricting them to apps that opt into them

  • Adds supports for more font weights when using FontFamily.SansSerif, even on older Android versions

  • Tweaks the PointerInputChange API

  • Adds LazyLayout() for your own lazy composables

Also, we got 1.0.0-alpha21 of Wear Compose, with a bunch of new options for curved content, a new SwipeDismissableNavHostState, changes to autoCenter, and a lot more!

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can You Create a Reusable Modifier in Compose?

If you find yourself repeating the same Modifier chain, you might want to create a custom Modifier that represents that chain. See a few techniques for doing this in this week’s highlighted Stack Overflow question.

How Big Should a Composable Be?

Should a composable function be capped at 50 lines? 100? 500? A few developers debated this, in this week’s highlighted Kotlinlang #compose Slack thread!

Composable Commentary

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

Twitter going all in on Jetpack Compose for feature development

This is an official “puff piece” from Google on the use of Compose UI by Twitter, explaining what development process improvements Twitter is seeing from making this change.

Medium: Alternatives to Idling Resources in Compose tests

A much more useful official post from Google comes by way of Jose Alcérreca. Jose reviews waitUntil() on ComposeTestRule to block test execution until some state is achieved. This can be used in lieu of Espresso-style idling or the never-reliable delay() approach to wait for some work to complete before proceeding to test the UI.

Medium: Automating Beautiful Screenshots Using Jetpack Compose

Medium user sinasamaki examines how to grab screenshots from instrumented tests, then how to automate collecting those screenshots using Fastlane.

Medium: Jetpack Compose: Runtime Permissions

Erselan Khan looks at Accompanist’s tools for requesting runtime permissions, centered around the rememberPermissionState() and rememberMultiplePermissionsState() functions.

Medium: Exploring Google Map Compose Library For Android

Stephen Vinouze returns, examining the official composable wrapper for Google Maps. Stephen specifically looks at how to add markers and how to address those markers as the user pans and zooms the map.

Resource Roundup

100% pure code!

GitHub: adrielcafe / bonsai

Adriel Café planted a Bonsai() tree widget composable, supporting both Compose UI for Android and Compose for Desktop. You can create your tree structure through a DSL or via filesystem or JSON integration.

GitHub: patrykandpatryk / vico

GitHub user patrykandpatryk created a chart library for Compose UI and the classic View system, though not by the traditional interop approaches (e.g., using AndroidView() to wrap the View in a composable). The library supports bar and line charts, including a combined “composed” chart.

GitHub: JustinGuedes / redactable-android

Justin Guedes brings us a LoadableView() wrapper composable that will render your UI with “redacted” content, showing a shimmer effect, while you load the actual content.

Gist: okmanideep / EventQueue.kt

Manideep Polireddi created an EventQueue implementation, designed for composables to be able to react to events coming from a viewmodel. See this Twitter thread for usage notes.

…And One More Thing

When we ask why certain official composables do not offer Feature X, we are often told “it’s all open source, just copy and modify the composable to do what you want”. While true, this approach has a variety of problems. One of those problems: some official composables cannot be copied, because they rely on internal APIs.

For example, as part of an upcoming blog post series, I wanted to create a Presentation() composable. In the Android SDK, Presentation is a key way to get content onto external displays. For reasons I have never really understood, Presentation is a subclass of Dialog. But, since Compose UI has a Dialog() composable, I figured that I could copy it and tweak the implementation to use a Presentation instead of a Dialog.

That… did not work. A fair bit of the Dialog() implementation relies on internal APIs. Most notably, the content of the dialog is handled by a DialogLayout class that extends AbstractComposeView and overrides some internal functions.

It is not out of the question that I could hack away at things and eventually get rid of those internal references. For the purposes of a demonstration in a blog post, I elected to go a different route.

Most of the composables that we are suggested to clone and modify will be farther away from low-level Compose UI plumbing. For example, wanting a Compose Material widget that goes against Material Design in one area is likely to be relatively easy to address. However, the closer you get to the Android SDK, the more likely it is that you will run into places where the code that you are copying depends on being part of Compose UI itself, as Dialog() does.