Newsletter Issue #93

Published: 2021-11-30

This week, we look at state management, every Compose developer’s favorite topic! We also look at navigation and reflection, along with displaying large images or chips in fields. And Chris Banes shows us how to fix a nested scrolling limitation when working with both composables and classic Views.

Also, UI testing is a pain, so we will spend a bunch of time on testing.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Do I Align to a Centered Item?

Sometimes, you want a UI element (e.g., a button) centered in an area, but then another UI element (e.g., some text) positioned relative to that centered item. You can accomplish this without necessarily needing to break out ConstraintLayout, as we see in this week’s highlighted Stack Overflow question.

How Do I Write End-to-End Tests?

A lot of the emphasis in Compose UI testing is on testing leaf composables. But, what if you want to test larger units, such as screens or the whole app? What do we use? Learn more in this week’s highlighted Kotlinlang #compose Slack thread!

Composable Commentary

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

droidcon London 2021

droidcon London had some Compose UI presentations, including Michael Bailey discussing UI testing and Joe Birch covering accessibility. There may be more Compose-related presentations than those two, but the droidcon site’s “Load More” button does not, indeed, want to load more. ¯\_(ツ)_/¯

Two Mutables Don’t Make a Right

Google’s Zach Klippenstein offers up this bit of wisdom: “Don’t put mutable collections in mutable state holders”. Zach then proceeds to back that up with a detailed explanation of why this rarely works the way that you want and what the alternatives are.

Medium: Why Bother remember() State in Jetpack Compose?

A related bug is forgetting to remember(). Po C explains what remember() does, why we need it, and what happens when we try to skip the remember() call.

Hacking the Hinge

Thomas Künneth is back, continuing to work at the intersection of composables and foldables (comfoldables?). Thomas’ particular interest is in foldables, like the Microsoft Surface Duo, where the hinge blocks out portions of the UI. Thomas explores ways of reworking your UI to try to avoid having critical bits overlap the hinge.

Safe Compose Arguments

Dilraj Singh created a library that uses annotations for generating Navigation for Compose routes. In this post, Dilraj explains the need for the library, how to use it, and how it generates the code using KSP.

Medium: Using Reflection to Modify Compose UI in Android

Ideally, you never need to use the techniques outlined in this article. However, there may be times when you are stuck, needing to match a design and where the existing composables lack sufficient flexibility. In this case, Jamal Mulla needed to modify the border width of an OutlinedTextField() composable… and wound up using reflection to modify the TextFieldImpl object representing the field.

Medium: Bottom Navigation in Jetpack Compose

Muhammad Danish walks us through using Navigation for Compose, Scaffold(), and BottomNavigation() to add a bottom navigation bar that routes users to different screens.

Resource Roundup

100% pure code!

GitHub: tom5079 / SubSampledImage

Rendering huge images has long been a challenge in Android, with ImageView wrapper libraries offering pinch-to-zoom and panning within the larger image. GitHub user tom5079 is working on a SubSampledImage() composable to offer a similar feature set within Compose UI.

Gist: chrisbanes / ViewInteropNestedScrollConnection.kt

Chris Banes brings us a workaround for a Compose-View interoperability issue: scrolling composables nested in scrolling views do not handle nested scrolling well.

GitHub: sdoward / pulsar

GitHub shows a “contribution chart” for each repository, using differently-colored squares to show how many contributions have been made over time. Sam Doward is working on a composable edition of that sort of chart, using your choice of shapes, colors, and more!

GitHub: dokar3 / ChipTextField

GitHub user dokar3 brings us a ChipTextField() composable, one that converts keywords into chips that can contain icons, removal buttons, etc.

GitHub: KasperskyLab / Kaspresso

Kasperksy Lab’s Espresso/UiAutomator wrapper library now has Compose UI support in “early access”.

…And One More Thing

In this week’s One Off the Slack, Colton Idle pointed out:

The compose testing docs seem to be more about testing specific composables.

Colton is correct: docs like this are aimed at smaller tests for smaller composables. The sole material on this subject is in the “Testing in isolation” section (emphasis added):

ComposeTestRule lets you start an activity displaying any composable: your full application, a single screen, or a small element. It’s also a good practice to check that your composables are correctly encapsulated and they work independently, allowing for easier and more focused UI testing.

This doesn’t mean you should only create unit UI tests. UI tests scoping larger parts of your UI are also very important.

That is a fine statement, but we are going to need more to go on, both in terms of the mechanics of writing larger UI tests and on all of the stuff that we will need to support them. For example, Compose testing has its own concept of idling resources, akin to the Espresso ones, but with limited documentation on how to create them and the circumstances under which you may need them.

To me, 2022 is the year for ramping up Compose to larger scales. Between the efforts of the Compose teams at Google and JetBrains, and the work of the broader development community, we are going to need to build up a knowledge base of how to work with Compose across a decent-sized app. Ideally, that would include more knowledge on end-to-end UI testing. Lots of teams have de-emphasized view-based UI testing, on the grounds that getting them to work reliably takes more effort than the teams can afford. If Compose is going to offer better options, we need them to be in place and ready to be used before those teams start working on migrating to Compose, so they can write the UI tests as part of that migration effort.

If your team has written end-to-end or other large-scale UI tests for Compose, spread the word! Write posts, record screencasts, deliver conference presentations, or otherwise let us know what you did, what worked, and what still needs some improvement.