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 aandroidx.compose.animation:animation-graphics
library -
There is a new
BrushPainter
API, for applying an arbitraryBrush
within aPainter
(akin to howColorPainter
applies an arbitraryColor
) -
TextField()
now clears the selection on BACK navigation, to better match how the platformEditText
widget works -
BadgeBox()
is nowBadgedBox()
and accepts aBadge()
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.
Other Interesting Links
- Medium: How to Show Date Picker in Jetpack Compose
- Video: ComposeView Comparisons
- Medium: LazyListState in Jetpack Compose
- Video: Mobile Developers React to Jetpack Compose 1.0
- Part 1, UI Widgets from Scratch in Jetpack Compose
- Kickstart your Android Project with Gong Base Project
- Video: Coil - Image Loading Library with Jetpack Compose
- Exploring App Bars in Jetpack Compose
- Medium: State in Jetpack Compose
- Medium: FlashChat : Jetpack Compose + Firebase
- Medium: Jetpack Compose VS SwiftUI !VS Flutter
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
).
Other Interesting Links
- GitHub: phansier / Coffeegram-Desktop
- Gist: creativedrewy / RoundedDiamondFabShape.kt
- GitHub: akshay2211 / NYTimes-Compose
- GitHub: yigit / ComposeCity
- GitHub: zsoltk / chesso
- GitHub: Xacalet / Minesweeper
- GitHub: jawa7 / GitHubApiApp
…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.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-12-03: Rebecca Franks on clipping and masking! Stefano Natali on graphicsLayer()! FunkyMuse on type-safe nav results! And... if we have enough maps, do we need to store our maps in a Map?!?
- 2024-11-26: Math! Shared element transitions! Custom modifiers! Macrobenchmark! Adapting to platform-specific design systems! And... why does wrapContentSize() not wrap my content size?!?
- 2024-11-19: Compose alphas! Compose Multiplatform patch! PaddingValues! Graphics layers! Swiping! Heatmaps! Navigation! And... why did we get a new production Compose BOM?!?