Newsletter Issue #207

Published: 2024-03-26

Another round of releases for the Compose BOM and Compose Compiler, so we check out what’s new!

In addition, we look at BoxWithConstraints() in lazy containers, play with dots and dashes (and hearts! đź’•), and run power through some circuits. And we look at a bunch of React-style hooks that you can now use in Compose.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

Compose Compiler is up to 1.5.11. Primarily it adds support for 1.9.23, along with including some bug fixes.

The Compose BOM is up to 2024.03.00, pulling in the 1.6.4 patch release for the main Compose artifacts, which contain bug fixes.

Compose 1.7.0-alpha05 is also out, with a variety of changes, including:

  • A temporary loss of hyperlink support in BasicText(), with a replacement coming sometime in the future

  • A new GraphicsLayer API “to record drawing commands in a display list as well as additional properties that affect the rendering of the display list”, along with other GraphicsLayer changes

  • Moved LocalLifecycleOwner from Compose UI to lifecycle-runtime-compose

Compose Material3 has a 1.3.0-alpha03 release, with some ExposedDropdownMenu() changes, some bug fixes, and other minor improvements.

Wear Compose is up to 1.4.0-alpha05, adding new public properties to ScalingLazyListState and FullScreenStrokeWidth, along with bug fixes.

And in Compose-adjacent artifacts, we have:

  • androidx.activity:activity-compose:1.9.0-beta01
  • androidx.fragment:fragment-compose:1.7.0-beta01
  • androidx.lifecycle:lifecycle-runtime-compose:2.8.0-alpha03
  • androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0-alpha03
  • androidx.navigation:navigation-compose:2.8.0-alpha05
  • androidx.paging:paging-compose:3.3.0-alpha05
  • androidx.paging:paging-compose-android:3.3.0-alpha05

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Does BoxWithConstraints() Work with LazyColumn()?

BoxWithConstraints() is great, but inside of a lazy container, it will get an infinite size along the lazy dimension (e.g., height for LazyColumn()). You will need to use other approaches to come up with a useful height, as we see in this week’s highlighted Stack Overflow question.

How Do I Repeat an AnimationSpec A Fixed Number of Times?

AnimationSpec for animateTo() on Animatable yields a very flexible API… if you can remember all of the available top-level animation functions. In this case, repeatable() repeats some other AnimationSpec a specified number of times, as we see in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Medium: Dot. Dash. Design

Katie Barnett is back, to teach us Morse code!

* looks more closely at Medium post *

No, actually, Katie is here to show us how to draw dotted and dashed lines in Compose UI, including stroke caps, using different shapes for the dots, and alternatives such as zig-zag lines.

Medium: Stop Passing Event/UI-Action Callbacks in Jetpack Compose

ilyas ipek points out that advice is not always universal. While “states flow down, events flow up” is good advice for any composable, the details matter. For highly reusable composables, the general recommendation is to have the states be simple types and the events be propagated by simple function types. However, for highly complex composables, such as screens, that can get unwieldy.

Retaining beyond ViewModels

Chris Banes explores Slack’s Circuit library, particularly how it lets you avoid some of the headaches involved with the Jetpack ViewModel system. In particular, Chris looks at what we get from Circuit’s concept of retained state and the recently-added support for observing when retained state is remembered and forgotten.

Capturing composable to a bitmap without losing a state

Shreyas Patil maintains the Capturable library for capturing a composable as a Bitmap. Google advises using the drawWithCache() / drawIntoCanvas() pattern. However, this can introduce bugs with stateful composables. Shreyas outlines an alternative approach in this post.

Creating a Color Picker Using Material 3 Slider Component

The Geeks for Geeks team walks us through using Compose Material3’s Slider() composable, specifically using three to control RGB values in a color picker.

Medium: Android Face Detection using MediaPipe and Jetpack Compose

Eldi Rohmanur examines Google’s MediaPipe, using it and the system camera to implement face detection within a Compose UI app.

Medium: Intrinsic measurements in Jetpack Compose

Oleg Green wanted two columns in a row to have the same height, based on whichever one was taller. The solution is to use IntrinsicSize.Max with the height() modifier on the containing Row(), with each Column() in the row set to have fillMaxHeight().

A quick example of how to model complex state in Jetpack compose

Tristan Elliott reminds us of the refactoring power in creating simple state classes and custom remember()-style functions.

Resource Roundup

100% pure code!

GitHub: junerver / ComposeHooks

Compose was inspired by React. So, Junerver Hou created a set of top-level functions that mimic popular React “hooks”, such as useRef(), useState(), useEffect(), and more.

GitHub: SimformSolutionsPvtLtd / SSComposeOTPPinView

I missed that, two years ago, the Simform Solutions team published their own OTP/PIN OtpView() composable, with control over colors, digit box stroke/color/size, and more.

Gist: oleggreen / SwipeButton.kt

Oleg Green created a SwipeButton() composable, for a button that is triggered not by a click but by a swipe.

Gist: sagar-viradiya / ThreadLikePathAnimation.kt

Sagar Viradiya was inspired by Threads’ loading animation to create a similar effect, with a path animation tracing the outline of the GitHub logo.