Newsletter Issue #60

Published: 2021-04-13

beta04 is out, and there are a few breaking changes — in this issue, we will take a look at those!

Also, we outline some text, react to some state, and animate all the things. We also see an IDE plugin for playing with modifiers, and we perhaps rate the result.

And, I screw up!

Beta Breakdown

Reviewing the release notes for the latest Jetpack Compose update!

As the Compose Runtime release notes mention, there was a bug with the handling of composable local functions (functions defined in functions). Basically, it was a case of premature optimization that is now fixed. If you had been avoiding local composable functions, you should be able to revisit them now.

As mentioned in the Compose UI release notes, hideSoftwareKeyboard() and showSoftwareKeyboard() on SoftwareKeyboardController are now just hide() and show(), saving you countless keystrokes! There is also live region support for accessibility, along with some fixes for view binding integration.

If you were trying to use RowScope, ColumnScope, BoxScope, or BoxWithConstraintsScope directly, rather than getting passed an instance from its associated composable… that’s no longer going to work, according to the Compose Foundation release notes.

Another possibly-breaking change is that DrawerState no longer extends SwipeableState, as is noted in the Compose Material release notes.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Creating Outlined Text

Sometimes, you might want text that has a different stroke color from the fill color, giving an outlined effect. While Text() offers no direct support for this, you can do it by drawing into a Canvas(), as we see in this week’s highlighted Stack Overflow question.

When Do We Use rememberSaveable()?

Officially, rememberSaveable() is for retaining state across short-term process termination, or for retaining state across configuration changes (if you have not opted out of those). Apparently, it has other uses as well, as we see in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

remember { mutableStateOf() } – A cheat sheet

Zach Klippenstein is back, this time with a post reviewing exactly what all the pieces of remember { mutableStateOf() } mean and how they work together to track state and force recompositions.

Video: Exploring Jetpack Compose: MVVM Architecture

Adam McNeilly recorded a two-hour Twitch session, taking a look at architectural concerns when crafting a Compose UI app, applying MVVM using Jetpack’s ViewModel along the way.

Video: Reactive State Management Using Jetpack Components

Gabor Varadi delivered a presentation for the Android Budapest Meetup, reviewing how we manage state and how reactive flows can improve upon classic approaches. The latter half of the presentation focuses on state management in a Compose-based app.

Video: Styling Text - Android Jetpack Comopose - Part 5

Philipp Lackner brings us a brief screencast showing how to customize your Text(), including using font resources, text decorations, and AnnotatedString.

Jetpack Compose Animations I

Gonzalo Campos offers us a general overview of the animation API in Compose, looking at things like AnimatedVisibility(), the animateContentSize() modifier, and the Transition system.

Android Jetpack Compose: Animation Spec Made Easy

Elye keeps writing about Compose! This time, Elye offers another look at the animations API, in this case focusing on AnimationSpec for describing how animations get applied (springs, keyframes, etc.) and looking at specific ones like FloatTweenSpec().

Part 1: Integrating Jetpack Compose to Our Development Code

Anang Kurniawan wrote a pair of posts about the use of Compose UI by Sampingan. In this post, Anang looks at how the team added Compose UI to the project and started in on the first composable of the overall refactor. In a follow-up post, Anang reviews problems that the team encountered with the canary version of Android Studio and how they worked around it… by dropping back to the stable release.

Jetpack Compose - Reveal Effect

Last week, I mentioned Benjamin Monjoie’s circular reveal animation gist. Benjamin since wrote up a post describing how it came about, including a few missteps along the way.

Compose CameraX on Android

Peng Jiang was working on integrating the Jetpack CameraX with Compose UI. Wrapping the PreviewView in an AndroidView() to create a composable worked reasonably well, and this post explains the details!

Resource Roundup

100% pure code!

Compose Modifiers Playground

Google’s Chris Sinco created an IDEA/Android Studio plugin that lets you play around with various modifiers to see their effects. The plugin itself is implemented in Compose for Desktop and is open source!

GitHub: aakarshrestha / compose-swipe-to-refresh

GitHub user aakarshrestha implemented a SwipeToRefresh() composable that implements a basic pull-to-refresh wrapper for your screen or other composable.

GitHub: a914-gowtham / compose-ratingbar

Gowtham Balamurugan put together a composable implementation of the RatingBar from the classic View system, with customizable drawables and colors.

GitHub: vitaviva / compose-tetris

It’s Tetris. Written with Compose UI. Do you really need me to say more?

…And One More Thing

When it comes to Compose, we are going to screw up a lot.

Compose’s Kotlin compiler plugin causes our compiled functions to be distinctly different from the functions that we wrote. As programmers, we are not used to that — we expect that what we run closely resembles what we wrote.

Sometimes, the difference will show up at compile time. For example, AFAIK, we still cannot have composable function references, even though from Kotlin’s standpoint, a function reference is interchangeable with a lambda expression.

Sometimes, the difference will be due to bugs in Compose itself. As noted in the “Beta Breakdown” section, local functions were not being handled quite correctly, causing required recompositions to be missed.

Sometimes, the difference will be subtle. Last week I linked to Zach Klippenstein’s post on recompositions. I went to reproduce Zach’s findings and was running into issues… because I did not read the post closely enough and missed that inline functions work differently than do regular functions with respect to the compiler plugin. Zach updated his post to add more material on that problem, and I am grateful for that change.

To an extent, tools will help here. For example, after my mistake with the inline function call, I filed a feature request to have Android Studio highlight calls to inline functions, such as through syntax highlighting or a gutter icon like we have for suspend calls. Similarly, expect an increasing number of Lint checks to yell at us as we do things that are on the edge of what Compose supports… or perhaps where we do things that blow past that edge entirely.

But a lot of this is going to wind up being handled by “institutional knowledge”.

If you have been doing Android development for a few years, your subconscious is already steering you towards avoiding hiccups in Android app development, for things that you have been burned on before. There is a whole class of bugs that crop up in your code when your subconscious is off having a cup of tea and you wind up getting burned by Android yet again. With Compose, we are starting from scratch with our mental models, and it will take some time for us to learn where we will still get burned and how to avoid those cases. This is natural, and the hope is that Compose UI is so much better than its predecessor that we will still be more productive despite making mistakes more frequently.

The bigger the change, the greater the likelihood of mistakes. Compose UI is perhaps the second-biggest change in Android history, after the adoption of Kotlin. Mistakes will happen. When it happens to you, share it with your team, write that blog post, or file that feature request for tool support. Collectively, we will get through this.