jetc.dev Newsletter Issue #96
We got slightly more than one RC release this past week — we’ll see what that means!
Beyond that, we look at child composables and how we pass colors down. We look at the alpha version of Jetpack Glance for creating app widgets. We explore custom password and multi-toggle button composables, plus swiping cards off of stacks and blocking Compose Material ripples. And I’m concerned about some advice from Chris Banes, which means I’m probably wrong, though perhaps I’m usefully wrong.
Reviewing the release notes for the latest Jetpack Compose update!
1.1.0-rc02 is out for
androidx.compose.compiler:compiler:1.1.0-rc02, with official support for Kotlin 1.6.10!
They also started publishing a table showing what Kotlin versions are supported
by which Compose compiler versions.
Note, though, that the rest of the Compose artifacts are still at
Mostly, those appear to be bug fixes. One that has a possible functional aspect:
LazyListState now support
negative scroll offsets.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
Surface() takes a
contentColor parameter, which affects the color of
things like the text of a
Text() that is a child of the
how this is accomplished in this week’s highlighted Stack Overflow thread.
DRY (“Don’t Repeat Yourself”) is a fine programming maxim, but sometimes defining
the single source of truth can be tricky. This is especially true in Compose UI,
where often Composable A cannot interrogate Composable B to get a value. Learn ways
of working around this in this week’s highlighted Kotlinlang
#compose Slack thread!
Posts, videos, and other new information related to Jetpack Compose!
Google has released the first alpha of Jetpack Glance, its new composable API for defining
app widgets and, in the future, Wear OS tiles and perhaps other “glanceable” targets.
One note: while the
minSdkVersion is set to 21, Glance really only supports back to API Level 23.
Matthew Meehan wasted no time in putting the Jetpack Glance alpha to use, creating an
app widget to keep track of how many glasses of water you drink. Matthew explores the boundaries
of Jetpack Glance (hint: you still need a layout resource, for the widget preview), examines
for responding to click events, and more. Also: stay hydrated! 😁 🚰
Chetan Gupta wanted to use
@Preview with a composable that uses
In the end, that is not really practical, so Chetan walks through a workaround, involving
a run configuration to launch a custom preview activity. Or, avoid using Hilt directly in leaf
composables (the sorts of things that you want to preview).
Back in issue 83, I linked to cokoin, a Koin wrapper for use with Compose (both the Compose Multiplatform and Google’s Jetpack edition). Here, Bruno Wieczorek explains the origins of cokoin, why it is a separate library, and how it works.
Juan Guillermo Gómez Torres explores a
including its use of
VisualTransformation, its options for password strength
calculations (for creating new passwords), and more!
Chizoba Ogbonna reviews
MaterialTheme() and its component parts (colors, typography, shapes, etc.)
and how you can tailor them to match your target designs. Chizoba also looks at
theme adapters for Material Component for Android and AppCompat, if you need
to share theme definitions between composables and classic
Other Interesting Links
- How to use highlight.js in your Jetpack Compose Web project
- Medium: Jetpack Compose 3- Theming
- Medium: Places Autocomplete Widget from Compose without fragment (using intent)
- Medium: Fundamentals of Jetpack Compose
100% pure code!
Other Interesting Links
…And One More Thing
About two months ago, Chris Banes wrote “Always provide a Modifier parameter”. This was well-received by the community, and I agree with its arguments in some situations. IMHO, though, its recommendations require more nuance for the overall ecosystem.
Other Compose UI experts extol the benefits of creating composables that implement a design system, whether that design system is wrapped around Compose Material or is created as a peer of Compose Material (based on pre-Material composables). IMHO, that is the better goal. There should be little question in the development team of how to assemble a Compose-based UI for your app: it should be based on a set of composables that in turn are based on what the designers ask for. Or, if the project lacks designers, there should still be a set of common UI elements that get applied consistently throughout the app.
Chris’ post does not prohibit the creation of composables for a design system. However, Chris’ objective appears to be maximum flexibility, and that can conflict with creating composables for a design system. Composables for a design system need to reliably implement the design system, more so than being flexible.
Chris’ final code snippet contains comments like:
// We can add any behavior we wish here!
/** * This now has a modifier parameter, allowing callers * to customize the layout, behavior and more! */
When implementing composables for a design system, those can be bugs, not features,
if they allow the composables to be used in ways that do not adhere to the designs.
Modifier is very flexible, exposing a
Modifier parameter all but guarantees
that the composables can be used in ways that do not adhere to the designs.
So, now we get down to team mechanics: is it better to have an API that is inflexible
but is reliable, or is it better to have an API that is flexible but unreliable? Stronger
teams can accomplish more in less time with the flexible-but-unreliable API, as they can
rely upon external processes to enforce the design where the composables do not. For
example, those teams have a large enough design team, or have a design-savvy QA team, such that they
can do design reviews to ensure adherence to the designs. Not
everyone has that sort of staffing, though. Or, they have teams with a lot of junior
developers, ones for whom adhering to a design system is a new concept. For those,
having an inflexible-but-reliable API may be the better course of action, even if it
means creating a couple of renditions of a composable (perhaps wrapping around a
private implementation) to handle varying scenarios.
In time, perhaps with tooling improvements we will be able to create composables
that are both flexible and reliable. For example, we could work out a way to validate
Modifier input to ensure that it does not mess with things that it should not.
Right now, I do not think we are in position to perform that sort of validation.
Does this mean that you should never expose a
Modifier input to your composables?
Of course not. It does mean that you should think through the short-term and long-term
role of the composables that you create, and consider whether supporting
is the right answer. It may be that the right answer is not “always” or “never” offer
Modifier input, but rather “sometimes”, such as “only for
- 2023-09-12: Compose 1.5.1! Glance 1.0.0! Compose Multiplatform! Themes! Photos! Coachmarks! A bit of CommonsWare history! And @firstname.lastname@example.org tells us what not to do!
- 2023-09-05: Compose Compiler 1.5.3! Compose Multiplatform 1.5.0! @email@example.com on greyscaling composables! @firstname.lastname@example.org on Espresso testing with Compose interop! Scrollbars! AnnotatedString!
- 2023-08-29: Compose Compiler 1.5.2! Compose and Wear Compose alphas! Capture composables to bitmaps! Testing! Recomposition! Compose Multiplatform! And... Accompanist is downsizing?!?