Newsletter Issue #209

Published: 2024-04-09

This week, we start by looking at all sorts of updates, from the Compose BOM and new Compose alphas to Glance, Wear Compose, and more!

We also play with shapes, poke around with Compose Multiplatform (plus Kotlin Multiplatform and per-platform UIs), and see how to treat focus as state. We also pick a reaction and segment a progress bar.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

The Compose BOM is up to 2024.04.00, mostly containing 1.6.5 patch releases, which seem to be fairly minor.

We also got 1.7.0-alpha06 of the main Compose artifacts. Those include:

  • Item appearance and disappearance support for lazy containers

  • Support for converting limited HTML into AnnotatedString via a parseAsHtml() function

  • Extended screenshot support with an experimental implementation of long screenshots of scrolling containers

  • A whole bunch of API refactoring

  • More flexible support for mixing-and-matching Compose foundation library versions, especially with Compose Material

Compose Material3 is up to 1.3.0-alpha04. It offers:

  • A couple of new experimental carousel implementations: HorizontalMultiBrowseCarousel() and HorizontalUncontainedCarousel()

  • Optional support for predictive back with ModalDrawerSheet() and DismissableDrawerSheet()

  • Support for custom heights of top app bars

Glance has a 1.1.0-beta01 release. This has no documented changes from the preceding alpha, though the commit list shows some preview improvements and bug fixes.

Wear Compose received a 1.3.1 patch release, fixing a swipe-to-reveal bug.

Wear Compose also has a 1.4.0-alpha06 release. This begins the process of adding rotary input and haptics support directly, rather than having to rely on Horologist.

And in Compose-adjacent artifacts, we got:

  • androidx.activity:activity-compose:1.9.0-rc01
  • androidx.fragment:fragment-compose:1.7.0-rc01 and androidx.fragment:fragment-compose:1.8.0-alpha01
  • androidx.lifecycle:lifecycle-runtime-compose:2.8.0-alpha04
  • androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0-alpha04
  • androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.0-alpha04 (new!)
  • androidx.lifecycle:lifecycle-viewmodel-compose-desktop:2.8.0-alpha04 (also new!)
  • androidx.navigation:navigation-compose:2.8.0-alpha06
  • androidx.paging:paging-compose:3.3.0-beta01
  • androidx.paging:paging-compose-android:3.3.0-beta01

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Why Does the Wrong Die Roll?

By default, when appending items to a lazy container, the assumption is that they will go on the end, such as on the bottom of a LazyColumn(). If you are looking to control the order better, use the key, as we see in this week’s highlighted Stack Overflow question.

Why Are My State Changes Ignored?

The question seemed almost simple: why do two changes within a SideEffect seem to get conflated? The thread explores that, along with limitations of Media3/ExoPlayer, the behavior of snapshotFlow() (especially under heavy multi-threaded load), the use of withMutableSnapshot(), and more. See the whole discussion in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Medium: Introducing Trio | Part II

Eli Hart continues his overview of Airbnb’s Trio framework. In this post, Eli explains the benefits of Trio considering navigation to be part of state, powered by a multi-module-friendly router implementation.

Medium: Fun with the circle shape in Compose

Last week, I pointed out Justin George’s library for clipped circles. Justin wrote a post explaining how he created that implementation.

Medium: Mastering Shapes in Jetpack Compose

Bhoomi Vaghasiya Gadhiya looks more generally at the Compose Shape interface and GenericShape implementation, demonstrating how you can create your own custom shapes each way and how to apply them to existing composables.

Jetpack Compose to Compose Multiplatform: Transition Guide

Gustavo Fão Valvassori walks us through the steps to take an Android app powered by Compose UI and convert its Gradle and source set configuration to use Compose Multiplatform instead.

Medium: Compose MultiPlatform shared UI with KMP (Part 1)

Nimit Raja also explores the basic setup of Compose Multiplatform projects and how to share UI between platforms.

Medium: Navigating the Waters of Kotlin Multiplatform: Exploring Navigation Solutions

If you are going with Kotlin Mulitplatform and per-platform UI implementations, you need to decide how you are going to manage navigation. Thomas Kioko reports on experiments with Voyager and Decompose, settling on Decompose for its better support of per-platform UI.

Medium: Jetpack Compose Multiplatform Scrollbar/Scrolling

Scrollbar behavior varies a bit depending on whether the UI is touch-centric (e.g., phones) or is mouse-centric (e.g., desktops). Kerry Bisset examines what it takes to manage scrollbars in Compose Multiplatform and take the particular scrollbar style into account.

Substack: Focus as a state - new effective Android TV focus management system with Jetpack Compose

TV Compose has nice support for focus management, but it is substantially behind the latest-and-greatest versions of Compose. Alex Zaitsev wanted to use ordinary Compose UI on a TV app, but then had to deal with focus management. Alex’s solution was to turn focus into part of the state, enhancing testability along the way.

Medium: Spotify-Inspired Audio Buffering Slider Animation with Jetpack Compose

Konstantin Merenkov liked Spotify’s implementation of a progress animation on the slider that controls the position within the song. Konstantin demonstrates how to achieve this effect using Material3’s Slider() and a custom pulsing modifier.

Resource Roundup

100% pure code!

GitHub: amsavarthan / reaction-picker

Amsavarthan LV created a reaction selection bar, with a UX reminiscent of Facebook’s, with an embiggened reaction icon and caption showing for the currently-selected choice.

GitHub: dalafiarisamuel / composeblurhash

Dalafiari Samuel offers us a rememberBlurHashPainter() that creates an image painter that works off of a blur hash string rather than an actual image. The idea is to get that string via your Web service API and use this as a placeholder while you download the full image.

Gist: svenjacobs / SegmentedProgressBar.kt

Sven Jacobs brings us a SegmentedProgressBar() implementation in 50 lines (not counting imports). See this Mastodon post for what it looks like!

Notable Releases

Google’s compose-pay-button library has is 1.0.0 milestone release. This includes preliminary @Preview support plus support for enabled and disabled states.

Nicos Nicolaou’s ImagePickerAndroid library is up to 2.0.9, mostly to catch up on newer Compose libraries and improve the libs.version.toml documentation.