jetc.dev Newsletter Issue #235

Published: 2024-10-08

We got Compose and Compose Multiplatform updates, so we unpack what arrived!

In addition, we look at screenshot testing, map markers, and LazyRow(). We examine a Compose Multiplatform charting library. And I wonder why some recent new UI elements from Google are not native to Compose.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

We got a new Compose BOM, 2024.09.03, with the 1.7.3 Compose patch release, containing bug fixes.

We also got a 1.8.0-alpha03 Compose release. Of note:

  • rememberCoroutineScope() now creates its child context lazily, to optimize cases where it is never used

  • They added a new Carousel semantics role

  • They removed an implicit graphicsLayer() modifier from BasicText, with a flag to add it back if that causes compatibility issues for anyone

  • They added a recalculateWindowInsets() modifier

  • They have not released documentation for the update to Compose Material

Compose Material3 is up to 1.4.0-alpha01. Of note:

  • Material3 no longer depends on material-icons-core, so you may need to add that dependency to your project

  • They changed the active color of NavigationBarItem and NavigationRailItem to be secondary instead of onSurface

  • They added TextField() and OutlinedTextField() composables that use TextFieldState

Also note that Compose Material3 got a few new artifacts:

  • androidx.compose.material3:material3-adaptive-navigation-suite-jvmstubs
  • androidx.compose.material3:material3-jvmstubs
  • androidx.compose.material3:material3-linuxx64stubs
  • androidx.compose.material3:material3-window-size-class-jvmstubs
  • androidx.compose.material3:material3-window-size-class-linuxx64stubs

Wear Compose is out with a 1.5.0-alpha03 release, with new HorizontalPager() and VerticalPager() components, bi-directional swipe support for SwipeToReveal() and more.

In Compose-adjacent libraries, we got:

  • androidx.camera:camera-compose:1.5.0-alpha02
  • androidx.camera.viewfinder:viewfinder-compose:1.4.0-alpha09
  • androidx.fragment:fragment-compose:1.8.4
  • androidx.lifecycle:lifecycle-runtime-compose:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-runtime-compose-android:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-runtime-compose-jvmstubs:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-runtime-compose-linuxx64stubs:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-viewmodel-compose:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-viewmodel-compose-android:2.9.0-alpha04
  • androidx.lifecycle:lifecycle-viewmodel-compose-desktop:2.9.0-alpha04
  • androidx.navigation:navigation-compose:2.8.2
  • androidx.navigation:navigation-fragment-compose:2.8.2

And JetBrains released 1.7.0-rc01 of Compose Multiplatform, with Kotlin 1.9.25 support and several fixes.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can I Make a Rounded Square Progress Indicator?

Given a Canvas, (almost) all things are possible in Compose, though you need to be comfortable with lower-level drawing APIs. Implementing progress indicators beyond simple shapes often requires a Canvas, such as this week’s example of a rounded square progress indicator, from a Stack Overflow question.

What Should I Use for Snapshot Testing?

We have options for snapshot testing, with Paparazzi, Roborazzi, and Compose Preview Screenshot Testing among them. Which should we use? Alas, “all options have their own tradeoffs”, as one person put it, seems to be the answer. We explore pros and cons in this week’s highlighted Kotlinlang #compose-android Slack thread.

Composable Commentary

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

Google Maps in Jetpack Compose: Markers

Joe Birch (@hitherejoe@androiddev.social) continues a tour of Maps for Compose, this time looking at Marker() and its various options. Joe looks at responding to clicks on the marker or an associated info window, how to change the marker icon, and more.

Medium: How to Create a Pulse Effect in Jetpack Compose

Medium user Kappdev shows how to implement a pulseEffect() modifier, which wraps a composable in another that renders a animated expanding pulse emanating from the original composable. This is often used to highlight a widget when first encountered or otherwise call attention to something that might be otherwise missed.

Medium: Mastering LazyRow in Jetpack Compose: A Comprehensive Guide with Examples

Ramadan Sayed takes a deep dive into LazyRow(), from simple use cases to having external control over scrolling, animating adds and removes, supporting mixed types of content, and more!

Medium: Reducing GPU Overdraw for Android view: A Guide for Developers

We used to worry a lot about overdraw back in the day. While modern GPUs help minimize the impact of re-re-re-re-re-redrawing the same pixel, we can still gain some performance and reduce some battery consumption by cleaning up overdraw. Shivang Sharma explains what overdraw is, how to measure it, and some “low-hanging fruit” for reducing it.

Build Your First Android and iOS Mobile App With Kotlin Multiplatform

Jaewoong Eum (@skydoves@androiddev.social) walks us through the distinction between Kotlin Multiplatform (KMP) and Compose Multiplatform (KMP), then helps us set up a CMP project in Android Studio.

Medium: Coil: My Favorite Image Loading Library for Jetpack Compose

Stefano Natali reviews Coil, a popular image-loading library for Kotlin. Stefano covers basic usage plus some advanced scenarios, such as rendering GIFs.

Using Circuit with kotlin-inject in a Kotlin/Compose Multiplatform project

John O’Reilly (@oreillyj@mastodon.social) explores using Circuit in a Compose Multiplatform project, in conjunction with kotlin-inject for dependency inversion. John applied Circuit to his BikeShare app and demonstrates its use on one of the BikeShare screens.

Medium: Supercharge Your Android App: Jetpack Compose Performance Hacks

Gastón Saillén has posted a long list of tips for development-time and runtime performance, from using key() to Gradle tuning to BenchmarkRule() and logging recomposition counts.

Resource Roundup

100% pure code!

GitHub: ArjunJadeja / texty

Arjun Jadeja has published a Compose Multiplatform library with many animated forms of text, from chat bubbles and simulated typing to a time indicator and iterating through a series of text snippets with animations.

GitHub: AndroidPoet / Drafter

Ranbir Singh (@androidpoet@androiddev.social) published a Compose Multiplatform charting library, supporting bar, histogram, line, pie, scatter, and waterfall charts, complete with animated effects.

GitHub: muhammadzubair906 / Koranger

Muhammad Zubair released a RangeBar() composable, supporting selection of a range of values. It offers horizontal or vertical orientation, customizable colors, and more.

Notable Releases

CashApp’s Redwood is up to 0.15.0, removing Compose for Web/Wasm support, adding a new ResizableWidget interface, and fixing several bugs, among other changes.

…And One More Thing

The new AndroidX Ink family of libraries is implemented using a View, rather than using Compose.

Similarly, the new PDF viewer is based on views, not composables.

Tactically, this is fine. We should be able to use these things in Compose UI via interop facilities. Also, it means that developers still centered around views are not necessarily going to need the overhead of Compose libraries.

Still, it feels weird that new, non-framework UI of significance is being offered purely using views. Even if they want a Compose-free implementation for View-centric development, it surprises me that this is their first option. If Compose is where Android is going, why not start there, then backfill in a View-only implementation if demand warrants it?