jetc.dev Newsletter Issue #276

Published: 2025-08-05

This week, we look at our new Compose and Wear Compose RC releases. We morph shapes on watches, play with AnimationSpec, and set up our common Compose Multiplatform previews. Plus, we look at a sweet library for animating text changes via automatic diffing.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

The Compose alpha and beta BOMs got bumped to 2025.07.01. The main Compose libraries are now at 1.9.0-rc01, as we get nearer to a stable 1.9.0 release. This mostly contains bug fixes, but do note that TextFieldState.edit() no longer clears the undo history.

Wear Compose is up to 1.5.0-rc01. This too is focused on bug fixes, notably in how locales impact DatePicker() and TimePicker().

We also got the following Compose-adjacent updates:

  • androidx.activity:activity-compose:1.12.0-alpha05
  • androidx.lifecycle:lifecycle-runtime-compose:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-android:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-desktop:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-iosarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-iossimulatorarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-iosx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-js:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-linuxarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-linuxx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-macosarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-macosx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-mingwx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-tvosarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-tvossimulatorarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-tvosx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-wasm-js:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-watchosarm32:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-watchosarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-watchosdevicearm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-watchossimulatorarm64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose-watchosx64:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-viewmodel-compose-android:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-viewmodel-compose-jvmstubs:2.10.0-alpha01
  • androidx.lifecycle:lifecycle-viewmodel-compose-linuxx64stubs:2.10.0-alpha01
  • androidx.media3:media3-ui-compose:1.8.0
  • androidx.navigation:navigation-compose:2.9.3
  • androidx.navigation:navigation-compose-android:2.9.3
  • androidx.navigation:navigation-compose-jvmstubs:2.9.3
  • androidx.navigation:navigation-compose-linuxx64stubs:2.9.3
  • androidx.navigation:navigation-fragment-compose:2.9.3
  • androidx.navigationevent:navigationevent-compose:1.0.0-alpha05
  • androidx.navigationevent:navigationevent-compose-android:1.0.0-alpha05
  • androidx.navigationevent:navigationevent-compose-jvmstubs:1.0.0-alpha05
  • androidx.navigationevent:navigationevent-compose-linuxx64stubs:1.0.0-alpha05
  • androidx.paging:paging-compose:3.4.0-alpha02
  • androidx.paging:paging-compose-android:3.4.0-alpha02
  • androidx.savedstate:savedstate-compose:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-android:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-desktop:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-iosarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-iossimulatorarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-iosx64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-js:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-linuxarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-linuxx64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-macosarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-macosx64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-mingwx64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-tvosarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-tvossimulatorarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-tvosx64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-wasm-js:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-watchosarm32:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-watchosarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-watchosdevicearm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-watchossimulatorarm64:1.4.0-alpha01
  • androidx.savedstate:savedstate-compose-watchosx64:1.4.0-alpha01

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can I Add a Trailing Icon to Text?

TextView has drawableEnd, which specifies an image to append to the text, wrapping with the text. The equivalent in Compose comes from AnnotatedString, rather than a composable like BasicText(), as we see in this week’s highlighted Stack Overflow question.

Why Do We key()?

While we tend to think of key() for use in lazy containers, it has wider use… though sometimes it is hard to understand the scenarios in which it benefits us. Learn how it replaces positions with identities, and what that means, in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Video: WearOS Material 3 shape morphing

Google’s Chiara Chiappini walks us through using ButtonGroup() and FilledIconButton() from Wear Compose Material 3 to tie size and shape of buttons to click interactions.

Video: The Easing Symphony: AnimationSpec in detail!

Nicole Terc (Bluesky) delivered a KotlinConf 2025 presentation exploring AnimationSpec and its various types, including customizing their easing curves.

Setting up Compose Multiplatform previews

Márton Braun (Mastodon, Bluesky) shows us how to implement Compose previews for common composables in a Compose Multiplatform project, when using Android Studio or IntelliJ IDEA on macOS, with an alternative solution for Windows and Linux users.

Medium: Previewing retain{} API: A New Way to Persist State in Jetpack Compose

Jaewoong Eum (Mastodon, Bluesky) explores the work-in-progress retain() API. This is a way for a composable to hold onto state that outlives its composition — by contrast, remember() only works until the composition is removed. While this can also be handled by ViewModel, retain() might prove to be better for UI data that is not ready to be handed off to repositories and the like, such as in-flight user input.

Medium: Auto-sizing Text in Jetpack Compose with BasicText

Oğuzhan Aslan examines the autoSize parameter to BasicText() and composables that wrap it (e.g., Text()). Oğuzhan explores many of the auto-sizing rules and options, supplied via the TextAutoSize value supplied for autoSize, including minimum and maximum font sizes to use.

Some thoughts on keyboard shortcuts on Android

Thomas Künneth (Bluesky) explains how to respond to keyboard shortcuts, whether doing so in an Activity via onProvideKeyboardShortcuts() and onKeyShortcut(), plus how to represent the keyboard shortcuts in a Compose-powered menu.

Medium: Deform the canvas

Alex Volkov shows how to stretch, twist, and otherwise morph the Canvas() that backs our composables, via the graphicsLayer() modifier and various bits of helper code.

Resource Roundup

100% pure code!

GitHub: Aghajari / AnimatedTextDiff

GitHub user Aghajari created a Compose for Android library (not yet published on an artifact repository) that animates changes between portions of text, using a text diffing algorithm coupled with configurable animation rules.

GitHub: ferPrieto / TimelineView

Fernando Prieto Moyano brings us a TimelineView() for synchronized scrolling of composables in a row, considered as “past content” and “future content”. This was originally created for visualizing audio waveforms and is implemented for Compose for Android.

GitHub: AJIEKCX / DeclarativeSnackbar

Alex Panov brings us SnackbarBox() and SnackbarComponent, for showing snackbars without a Scaffold() in your Compose Multiplatform project. This includes support for “global” snackbars, defined once for your entire UI.

GitHub: KvColorPalette / KvColorPicker-Android

GitHub user KvColorPalette offers us a KvColorPickerBottomSheet(), for choosing a color from a pre-defined roster or from RGB or HSL pickers. As the library name suggests, this is for Compose for Android.

Notable Releases

Horologist is up to 0.7.15, with bug fixes and dependency updates.

Circuit has reached 0.30.0, with bug fixes and dependency updates. It also moves ViewModelBackStackRecordLocalProvider to a different module, has it backed by the multiplatform ViewModel implementation, and now is used by default.

Compose Unstyled marched ahead to 1.39.0, adding TriStateCheckbox() and a focusRing() modifier, plus other changes, bug fixes, and dependency updates.

Redwood released 0.18.0, with greater support for internal composables, plus other changes, bug fixes, and dependency updates.

Finally, Vortex has a 0.2.6 release, with improved support for custom transitions.