jetc.dev Newsletter Issue #63
This week, we peek at
InteractionSource and how not to chain composables together.
We explore the impacts of Compose on dynamic feature modules and see how to offer
composable-specific modifiers. New libraries are available for settings, maps, and collapsing
app bars. And I warn you to make time for hallway testing as you migrate your app
to Compose UI.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
With things like button backgrounds, we used to use a
StateListDrawable to say “use these different images
based upon the state of the button”. This would allow us to have different images for the
pressed button state or the disabled button state from the normal button state. In Compose UI,
that tends to be handled differently, using
State that we observe. For states that depend on
user interaction, such as whether the composable is focused, there is
InteractionSource as a source
State, as we see in this week’s highlighted Stack Overflow question.
Using things like
DisposableEffect, it is possible to arrange for recomposition
of one composable to mutate state, which in turn triggers recomposition for some
other composable. This technically works, but it probably is not what you want, as we
see in this week’s highlighted Kotlinlang
#compose Slack thread.
Posts, videos, and other new information related to Jetpack Compose!
Gérard Paligot works through a sample Kotlin/Multiplatform project that uses both
Compose and Compose for Desktop. In particular, he shows how to share composables
between the platforms, including having common composables reference per-platform
Joe Birch has launched a Compose-specific podcast as an adjunct to the Compose Academy Web site.
While some modifiers are available everywhere, others are only available to child
composables of some specific composable. For example,
weight() is only available
for children of
Column(). This bit of magic is handled via extension
functions and a custom type as the receiver of the lambda expression that creates
those child composables, as Francesc Vilarino Guell explores in this post.
Julien Salvi continues a tour of Compose rendering, this time with a look at creating
Shape implementations. We supply
Shape objects to modifiers like
border(), but there are only a few stock implementations of
Shape. Here, Julien shows
creating one from scratch, using
Outline.Generic and a relatively complex
Annsh Singh writes a lot about Flutter, but is now playing around with Compose UI.
In this post, Annsh ported the “counter” app (Flutter’s “hello, world” equivalent)
to Compose UI, using
rememberSaveable() for retaining the counter state.
Other Interesting Links
100% pure code!
Bernat Borrás Paronella is working on a library of composables that offer similar functionality
Preference elements in a
the AOSP settings guidelines.
Right now, it covers simple links, plus switches and checkboxes, each in individual boxed
entries with titles and subtitles. (and TIL that AOSP has settings guidelines…)
Pierre Laurence offers up another library, this one for implemented tiled maps.
You provide sources of tiles (e.g., from files or Web services), and
takes care of loading tiles as the user pans, flings, and zooms.
Other Interesting Links
…And One More Thing
As Compose and Compose UI roll along towards a stable release, teams will start to think about beginning to use these technologies in their apps. Some of those teams will focus first on “new construction”: new apps or new screens in existing apps. Other teams will prefer to start by rewriting existing UI.
There is a hidden cost to the rewriting approach: ad-hoc “hallway” testing.
Many teams have automated UI testing, using instrumented tests, Espresso, and the like. However, many teams also wind up skipping those, as they are expensive to write, expensive to maintain, and slow to run. Those teams focus automated tests on lower levels of the app and rely on manual testing for the UI.
There is nothing strictly wrong with either of those approaches. One size does not fit all.
However, what often gets ignored is ad-hoc testing, the sorts of things that team members do on a day-in, day-out basis by using the app. If you have been doing software development for any significant length of time, you will be familiar with ad-hoc testing:
You do something in the app
Something unexpected occurs, causing reactions ranging from 🤨 and 🤔 to 🙄 or 😮 (or 😭 or 😱)
At some point, you take steps to investigate the unexpected behavior and perhaps make fixes
Sometimes, you literally are the one doing this testing. Sometimes, it it teammates. Sometimes, it is managers or other teams within your organization. And, alas, sometimes, it is customers or other end users.
All of that feeds back into the app and makes the app better. And much of that gets thrown out when you do a wholesale rewrite.
In the case of redoing a screen using Compose UI, improvements from ad-hoc testing that fix things deeper in the app might remain, but improvements that affect your views might be lost when you replace those views with composables.
This is not to say that should never rewrite UIs. Nor is this concern unique to Compose. However, Compose is one of the bigger externally-induced reasons for rewriting UIs, and in particular rewriting the UIs of entire apps.
Make sure that as you do these rewrites that you budget sufficient time for ad-hoc testing and that you let ad-hoc testers know about screen changes. Make sure that you have good channels for ad-hoc testers to report any oddities that they see in the Compose-ified screens. Make sure that those ad-hoc testers know how to provide good reports about those oddities: steps to reproduce the problem, screenshots/screencasts, etc. And make sure that your development process has ways to take that feedback into account and make repairs.
The advantage of first applying Compose to “new construction” is that, by definition, everybody knows that it is new. The sorts of people used to reporting weird stuff will tend to be watching out for problems with new screens, where they might not realize that a rewritten screen was rewritten.
Regardless, make sure that your “eyes and ears” across your organization — including trusted beta testers — are able to help you as you work through bugs related to a Compose migration, whether those bugs come from your migration or from Compose itself.
- 2023-11-21: Compose/Material3/Wear Compose updates! remember()! Adaptive layouts! Compose Multiplatform in 2024! @firstname.lastname@example.org on BasicTextField2()! Compose Multiplatform charts! And... is TV Compose in trouble?!?
- 2023-11-14: Compose Compiler! BasicTextField2()! @email@example.com and animations! Optimization! @firstname.lastname@example.org, JetBrains, and Fleet! JetBrains and plotting! And... we collapse?!?
- 2023-11-07: Compose Multiplatform! Chips in fields! Diffing! Custom fonts in Glance app widgets! Heatmaps! PIN input! And @email@example.com is in a bit of a haze?!?