jetc.dev Newsletter Issue #56

Published: 2021-03-16

beta02 is out… and it’s not a big deal! Our little UI toolkit is growing up! 🎉

So, in this week’s issue, we spend some time on performance issues, both inside and outside the IDE. We also look at Google’s Compose coding guidelines, animations, and Kotlin/Multiplatform projects using Compose UI. Plus we see what Leland Richardson’s code looks like. 👀

Beta Breakdown

Reviewing the release notes for the latest Jetpack Compose update!

beta02 was released!

So far, Google is keeping API changes to a minimum. If you had been using SoftwareKeyboardController, you will probably want to switch to LocalSoftwareKeyboardController. And if you were diving deep into Compose internals, you may run into some hiccups with experimental APIs.

But, on the whole, migrating to beta02 should be fairly straightforward.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Scaffold() Overlap Issues

Scaffold() is very easy to set up, but it has one usability bug: you need to use the PaddingValues passed to your content lambda. Otherwise, you may run into problems with Scaffold() elements, like a bottom nav bar, overlapping your content. Google’s Ian Lake reminds us of this in this week’s highlighted Stack Overflow question.

Why So Slow?

When you run your Compose app, it may appear more sluggish than you might expect. One reason for that might be live literals, as we explore in the “…And One More Thing” section later in this issue. But, more generally, it takes time for modern Android runtimes to optimize your app, as we see in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

API Guidelines for Jetpack Compose

Google published their documentation for how the Compose team names things, covering such topics as WhyComposablesCapitalizeTheFirstLetter(), WHY_THEY_DISLIKE_UPPER_SNAKE_CASE, and more. It also covers the expectations around public APIs (e.g., should a composable return a value?).

Android Jetpack Compose: CompositionLocal Made Easy

Elye is back, this time with two posts. This one looks at the CompositionLocal construct, Compose’s way of providing tree-global values without having to pass everything through function parameters. While dangerous, CompositionLocal has its uses. Elye also wrote a post looking at how to have your composables avoid window decorations using insets.

Better Handling States Between ViewModel and Composable

Igor Escodro walks us through some problems we may encounter when using hot flows with composables, and how switching to cold flows may help.

Re-gaining Orientation #1

Thomas Künneth goes where few developers seem to go nowadays: landscape mode. Thomas explores how we can detect changes between portrait and landscape and offer custom UI for each orientation.

Passing Parcelable / Serializable and Other Data in Jetpack Compose Navigation

Wajahat Karim takes a look at a sore spot with a lot of Compose developers: passing Parcelable objects via Navigation for Compose. The Compose team is trying to steer developers away from custom Parcelable objects, for good reasons. However, some Parcelable objects come from the framework, and we will need to pass those through Navigation from time to time.

Building a Scroll-to-Fade TopBar

Joe Birch builds upon the parallax effect that Julien Salvi wrote about a few weeks ago, using it to implement a top app bar that fades in as an associated content pane scrolls upward.

Jetpack Compose — Pulsating Effect

Paulo Pereira wanted to animate a composable’s scale to provide a pulsing effect. Paulo’s solution involved rememberInfiniteTransition() to animate a Float value to use with the scale() modifier.

A Jetpack Compose Tutorial for Beginners – How To Understand Composables & Recomposition

Ryan Michael Kay returns with with a recap of what composables, compositions, and recomposition all mean as terms within the Compose environment.

Resource Roundup

100% pure code!

GitHub: burnoo / compose-remember-preference

Bruno Wieczorek created a library with a family of remember...() functions that are backed by DataStore-based preferences, so your state is persisted automatically. Instead of using remember { mutableStateOf(...) }, you use functions like rememberStringPreference() or rememberBooleanPreference(), with control over keys, initial and default values, etc.

GitHub: Zhuinden / simple-stack-compose-integration

Gabor Varadi is working on Compose integration for his Simple Stack navigation engine, This post outlines how to use it, including animating changes between composables.

GitHub: mddanishansari / bootstrap-alert-compose

MD Danish Ansari has created an alert bar system reminiscent of those from the Bootstrap Web UI library, complete with dismiss actions.

GitHub: Gurupreet / FontAwesomeCompose

Gurupreet Singh has converted the Font Awesome library of icons into a Compose UI library, so you can use those icons as easily as you can use the Material Design icons that ship with Compose Material.

GitHub: russhwolf / To-Do

Russell Wolf is working on a Kotlin/Multiplatform edition of a classic to-do app, using Swift UI on iOS and Compose UI on Android. A shared module shares code between the platforms, including a SQLDelight-backed data store.

GitHub: Foso / MealApp

Jens Klingenberg is also working in Kotlin/Multiplatform, with Swift UI and Compose UI interfaces. In this case, the data is loaded from https://www.themealdb.com/, using Ktor for the network I/O.

GitHub: lelandrichardson/compose-dogfooding

Google’s Leland Richardson has been livestreaming some Compose coding sessions. This repo has links to those streams plus the code that he developed during those sessions.

GitHub: timusus / lift

Tim Malseed created a small app for managing weight lifting exercises, guiding you through your requested sequence of exercise sets and reps.

…And One More Thing

For mid- to large-sized projects, I have been recommending isolating the Compose-related code into a dedicated module (or modules), independent of other modules.

My original concern was namespace pollution. There are a tremendous number of top-level functions that Compose and Compose UI introduce. Those of us with decades of programming experience remember the “good” old days where everything was in a single namespace — the resulting collisions and confusion were anything but good. Minimizing the scope of Compose’s namespace pollution, by isolating its use to dedicated modules, can help with this.

Later, I was worried about Compose’s Kotlin compiler plugin. That plugin is fairly invasive, and so the less code it needs to process, the faster your builds will be and the fewer unexpected results you might get.

Now, we also need to think about the impacts of Compose-related tooling.

In this Stack Overflow question, a developer was seeing significant slowdowns when running Compose code in Android Studio. Via profiling, the developer determined that the problem lies in an isLiveLiteralsEnabled() call that happens in lots of places in the code.

This is tied to an Android Studio feature where composable previews can be updated in real time as you edit literals in your source code. This is an interesting feature, one that tries to bridge the gap between the preview system and “hot reload”-sorts of options available in other UI frameworks. However, this adds a lot of overhead.

The long-term solution is to minimize the size and scope modules where Compose is used, so live literals are fewer in number. For projects that are already experiencing problems, though:

  • Via a status bar menu, you can disable live literal processing

  • @NoLiveLiterals may be able to control this behavior for some scope

There is little doubt that Compose and its associated tooling is powerful today and will be more powerful tomorrow. That power has its costs, though, and that might steer you towards keeping your Compose-ified modules small and putting the rest of your code elsewhere.