jetc.dev Newsletter Issue #45
alpha09 is out, wrapping up the 2020 Compose releases! In this week’s issue,
we look at some of the
alpha09 changes. We also peek at how Compose impacts
our APK size and complexity, along with how to implement a staggered grid. We
see what a custom design system looks like, and I take a look at a
mistake that I made.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
We have lots of UI patterns with classic views that we will need to replicate in Compose UI.
One is the overflow menu in an app bar, for lower-priority items. With
Toolbar, we would use things like
app:showAsAction="never" in menu XML resources.
With Compose UI, instead, we create our own
DropdownMenu(), as we see in this week’s
highlighted Stack Overflow question.
Default values for things like padding are not a Compose thing — those decisions are part of a design system, such as Compose Material. That has an impact on the API that we wind up using, as we see in this week’s highlighted Kotlinlang Slack thread.
Posts, videos, and other new information related to Jetpack Compose!
If you were using
SlotWriter, they are no longer
part of the public API. Also, if you had been annotating properties with
@Composable, you will need to switch to annotating their getters with
They changed names again:
LazyRowFor() are deprecated, replaced
LazyRow(). However, they added a bunch of other features for
reverseLayout and custom arrangements. They extracted a
interface and added
There were quite a few changes (each small) this time — you should consider reading the full release notes. In particular, if you have been working with keyboard input, autofill, accessibility, or dialogs, you will want to peek at what has changed.
The biggest news, for those creating their own design systems, is that the ripple effect
for clicks has now been extracted into an
so you can use those ripples without needing the rest of Material. Also, watch out
for a bunch of renames related to
...Constants classes, as they are now
with changes in their property names to match.
Google’s Chris Banes rewrote his Tivi sample app using Compose UI. In this official Medium post, he compares the two implementations, not from a coding standpoint, but in terms of how big the resulting app is, in terms of APK size, build time, method counts, etc.
Elye’s second post looks at implementing a staggered vertical grid — columns
where the items in each column can vary in height — using Compose UI.
Specifically, he demonstrates how to use
Layout() to place child composables
at specific locations within a parent — in this case, controlling the number
of columns and taking into account the height of each element in a column.
droidcon APAC 2020 released the videos for their recent virtual developer conference! Three were focused on Compose and Compose UI. This one, by Himanshu Singh and Niharika Arora, focuses on the basics of using Compose UI.
100% pure code!
…And One More Thing
Everybody makes mistakes.
No programmer get very far in programming without having some sort of mistake, caught at compile-time or runtime. This is “part and parcel” of software development.
Newcomers to programming, or to a particular system, are more likely to make mistakes, owing to their relative inexperience. Moreover, newcomers are likely to make predictable mistakes. We see this all the time in classic Android development:
Developers who try calling methods from
Activityfrom a field or property initializer, before
onCreate()gets called, and fail because many of those inherited methods are not ready yet
Developers who try referencing a widget field or property before calling
findViewById()to populate that field or property, or calling
setContentView()(in an activity)
Developers who try working with files using bare filenames, as you can in desktop Java, rather than with fully-qualified paths, as you need in Android
And so on
A well-written system tries to help developers get past predictable mistakes quickly.
Sometimes, that comes from designing the API to avoid the mistakes. If the API prevents you from making mistakes, you are less likely to make mistakes. If the default use of the API prevents developers from making mistakes, newcomers are less likely to make mistakes initially, as often they will stick to the defaults.
Sometimes, that sort of API design is impractical. At that point, helping developers get past predictable mistakes comes down to having actionable error messages.
For example, this past Saturday, I was merging a couple of Compose samples together, and
I crashed with a
"The target value must have an associated anchor" error message
when trying to open a drawer attached to a
Scaffold(). It turns out that I missed
scaffoldState parameter to
Scaffold(), even though I was using
ScaffoldState elsewhere in the
Scaffold() setup. This was a classic copy-paste
problem, where I was copying individual parameters rather than the full
However, the error message
itself was completely unusable (what “target value”? what “anchor”?). I wound
up comparing and contrasting a working implementation with the failing one, until
I noticed the missing parameter.
As Elye points out,
Scaffold() is a fine starting point for a Compose screen. We should expect
newcomers to use
Scaffold() a lot. As a result, the more we can do to help
newcomers get their
Scaffold() implemented correctly, the more quickly
those newcomers will gain comfort with how Compose works. Failing to supply
scaffoldState is a predictable mistake; ideally,
Scaffold() fails in a way that helps newcomers understand what might have gone wrong.
As you start creating composables, for your team or for Android developers worldwide… ideally, think through how developers will make mistakes with those composables, then take steps to try to get developers past those mistakes.
- 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?!?