jetc.dev Newsletter Issue #77

Published: 2021-08-10

The dust barely settled on the first stable release, and we already have a new patch release plus our first 1.1.0 alpha!

This week, we peek at those releases, plus spend a fair bit of time contemplating an email-validating InputField(). We also learn about Compose Multiplatform and Accompanist Navigation Animation, look at accessibility and finite state machines, and see some Compose UI libraries for progress buttons, info bars, and more.

Release Ruminations and Alpha Analysis

Reviewing the release notes for the latest Jetpack Compose updates!

We have a new patch release, 1.0.1. This version uses Kotlin 1.5.21, but otherwise is unchanged, according to the release notes.

We also have the first new-version alpha: 1.1.0-alpha01. Of note:

  • AnimatedImageVector() is back, in a androidx.compose.animation:animation-graphics library

  • There is a new BrushPainter API, for applying an arbitrary Brush within a Painter (akin to how ColorPainter applies an arbitrary Color)

  • TextField() now clears the selection on BACK navigation, to better match how the platform EditText widget works

  • BadgeBox() is now BadgedBox() and accepts a Badge() as a parameter

  • Compose Material now has a NavigationRail() composable for your large-screen UIs

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Customizing Progress Animation

Sometimes, you might want to alter the stock animation for a CircularProgressIndicator(). You can tweak things like the damping ratio and stiffness using ProgressAnimationSpec, as we see in this week’s highlighted Stack Overflow question.

Where Should Validation Go?

We sometimes have cases where a specific composable might need to apply some input validation, such as requiring that a field contains a plausible email address. Where should that validation logic go? We explore a few options in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Compose Multiplatform goes Alpha, unifying Desktop, Web, and Android UIs

JetBrains has combined Compose for Desktop and Compose for Web under a common “Compose Multiplatform” brand. Compose Multiplatform is now considered to be an alpha, an upgrade over its previous developer preview status. They have also released a plugin for IDEA and Android Studio that enables @Preview support for Compose for Desktop. And, an number of other improvements were made to Compose for Desktop and Compose for Web as part of the alpha upgrade.

Video: Compose Multiplatform Alpha: The Story

As part of the Compose Multiplatform launch, JetBrains released a video combining several interviews with JetBrains and Google staff members, explaining the role of Compose Multiplatform and where things will be going in time.

Podcast: Android Developers Backstage on Compose Testing

Google’s Android Developer Backstage podcast takes a deeper dive into testing Compose UI apps, with Jose Alcérreca, Jelle Fresen, and Filip Pavlis contributing their views on the history of testing Compose UI, the problems inherent in View-based testing, and how Compose’s testing options improve on them.

Medium: Animations in Navigation Compose

Google’s Ian Lake gives us an update on the state of Navigation for Compose, the limitations on which Compose animation APIs it can use, where animations for Navigation for Compose are headed, and introducing the Accompanist Navigation Animation stopgap implementation.

Video: Compose Navigation Animations

Mitch Tabian continues his series of screencasts on Compose UI development, this time looking at the new Accompanist Navigation Animation library described by Ian Lake in the preceding entry.

Medium: Introducing Navigation-Material

Jossi Wolf is back, to announce another Accompanist library: Navigation-Material. This library adds navigation support for modal bottom sheets to the world of Compose UI.

Best Practice to Build Accessible Apps with Jetpack Compose

Fanny Demey wrote a post explaining how to improve the accessibility of Compose UI apps, from the basics of contentDescription to the more powerful semantics() modifier.

Finite State Machine as a ViewModel for Jetpack Compose Screens

Sergey Nes brings us a lengthy post that “does what it says on the tin”: it shows up to set up a state machine to map UI events to state mutations, where those states in turn drive a Compose UI.

Medium: Hoisting State in Composable Objects

Francesc Vilarino Guell returns, with a post highlighting the subject from the One Off the Slack post: how to hoist state for an email-specific InputField() where the state can handle basic validation of the email address.

Resource Roundup

100% pure code!

GitHub: SimformSolutionsPvtLtd / SSJetPackComposeProgressButton

Simform Solutions created a SSJetPackComposeProgressButton(), for a button that when clicked shows a progress indicator, followed by success or failure status indicators.

Gist: surajsau / Reorderable.kt

Suraj Kumar Sau supplied a short set of composables for implementing a manually-reorderable list, triggered via a long-click gesture.

GitHub: JuniperPhoton / FlipperLayoutJetpackCompose

GitHub user JuniperPhoton created a FlipperLayout() composable, to allow you to have an animated vertical 3D flip transition between two composables.

GitHub: radusalagean / info-bar-compose

Radu Salagean offers us an InfoBar() composable, designed to fill the same role as a snackbar, but without the framework requirements (e.g., some form of SnackbarHost).

…And One More Thing

This week’s One Off the Slack post highlights one aspect that makes migrating to Compose a bit challenging: with a new UI toolkit come new options and recommended patterns for classic problems.

That post considers where validation logic goes, for simple fixed validation rules like “is the text entered into this field an email address or not?”. The three possibilities examined there are:

  • The composable (e.g., EmailInput()) knows the validation rules

  • The viewmodel handles the validation rules, and the composable is just rendering things

  • Create a custom state object via an interface and let it handle the validation rules

The first two have clear analogues in the classic View system: an EmailEditText subclass of EditText could handle the email validation itself, or your viewmodel could handle the validation.

The custom state object option could also be done with a custom View. EmailEditText could accept some sort of state object via some function (e.g., bindState()). EmailEditText could forward events to that state object (e.g., via TextWatcher) and react to changes in the state itself to update the UI. However, this particular pattern was not often seen – developers would be more likely to go with either of the other two options.

But state objects abound in Compose UI. Any composable with state has its own state object. Creating a state object for a custom composable – one that perhaps wraps a stock state object and handles more business rules – is the sort of thing that should be natural. However, “muscle memory” of the classic View system may impede adoption of this approach for a while, until we get more used to the way that Compose UI works and how best to employ its various patterns.