Newsletter Issue #25

Published: 2020-08-04

This week, we look at upcoming state changes (literally, changes to state()). We also get a Google-level look at using @Preview, learn how to integrate ExoPlayer into Compose, and see a swipe-to-dismiss modifier implementation. And, I spend some time hoping for API design guidance from Google, as what they are learning now we need to learn before crafting a zillion Compose libraries.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Alas, we continue to collect few good answers in Stack Overflow in the android-jetpack-compose tag.

The Changing State of State

In an extensive Slack thread, Google’s Leland Richardson warns us of some likely API changes (no more state()!) and provides the rationale for why simple APIs sometimes might be too simple.

Composable Commentary

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

Video: What’s New in Compose Design Tools

In this YouTube video, Google’s Diego Perez demonstrates the Android Studio preview pane and its use with the @Preview annotation, including using @PreviewParameter to supply sample data to your composable preview.

Confirmation of Broken Previews

The counterpart to that video is this issue comment, where Google confirms that composable previews are presently broken in the current Android Studio 4.2 canary builds, if you are using dev15 or newer builds of Compose. The comment indicates that this will be fixed in 4.2 Canary 8.

Getting Started and Developing an Application with Jetpack Compose

Here, Muhammed Salih Güler gives us an introduction to Compose, including assembling a popular-movies list UI.

Await Next Frame in Jetpack Compose

Jorge Castillo returns with an explanation of some code, originally supplied by Google’s Adam Powell, for updating a State on each composition frame, as a way of driving an animation.

Playing a Video with Jetpack Compose

Halil Ozercan reviews integrating ExoPlayer in a Compose application, using AndroidView, to play back videos.

First Look at Jetpack Compose

Here, André Lopes provides a brief comparison of Jetpack Compose and Flutter.

Jetpack Compose - Desktop

Parthasarathy wrote up some notes on how to get the compose-desktop AOSP module building and running on Linux. This involved replacing the skija library with skiko, a new JetBrains library offering a Kotlin/Multiplatform wrapper for skija.

Composing in the Wild

Back in Issue #14, I showed you a project from Andrei Shikov, where he drove the content rendered in Web browser from a Kotlin server using Compose’s tree-manipulation logic. In this post, Andrei explains a bit more about how his experiment works.

Resource Roundup

100% pure code!

GitHub: halilozercan / ComposeVideoPlayer

This repo contains the code for the ExoPlayer-based Compose video sample that Halil Ozercan profiled in a post listed earlier in this newsletter!

GitHub: joreilly / BikeShare

John O’Reilly has put together a Kotlin/Multiplatform project that uses Compose and Swift UI, for supporting Android, iOS, and macOS. The app uses the CityBikes API for helping you find bike-share locations.

Gist: bmc08gt / SwipeToDelete.kt

Brandon McAnsh demonstrates a swipeToDelete() modifier for implementing a swipe-to-dismiss pattern, such as for a vertically-scrolling list.

GitHub: AndreySBer / Coffeegram

Andrey Beryukhov gives us another coffee app, this one with Compose and StateFlow in an MVI-style architecture.

GitHub: takahirom / jetpack-compose-markdown

Takahiro Menju demonstrates parsing Markdown and rendering it using Compose’s AnnotatedString.

…And One More Thing

This week’s “One Off the Slack” highlights a challenge with Compose: designing the right API. We all want APIs that are easy to understand and easy to integrate, but we are still learning how best to do that in the world of Compose.

For example, the swipe-to-dismiss modifier mentioned earlier in this issue is a simple Modifier extension function. This is nice, in that it can be easily added to a Modifier chain alongside all of the other modifiers that we use. Simply calling swipeToDelete() seems like it qualifies both as “easy to understand” and as “easy to integrate”.

However… is this modifier designed to be used anywhere?

This is one of the risks of defining top-level Modifier extensions: they are usable from any scope. That only works well if the modifier makes no assumptions about its surroundings. In this case, that probably is indeed true, and any conflicts are simply unfortunate (e.g., trying to drag horizontally in a horizontally-scrolling container).

However, in some cases, it may make more sense to tie a modifier to some particular scope, the way that RowScope has gravity() and weight() modifiers.

Google is working on documentation to help guide us in these decisions — Adam Powell has hinted a few times that he is working on such a guide. It seems likely that such guidance will be delayed until after the first alpha release, as today’s rules might run afoul of tomorrow’s breaking API changes.

And, no doubt, we will make mistakes along the way. For third-party developers, mistakes can be fixed. Google will not be afraid to make breaking changes — that is a big benefit of Compose being a library. However, there is some amount of “institutional knowledge” inertia that builds up the longer an API is around, so Google may be less inclined to make changes that will confuse a generation of developers.

As Compose proceeds through alpha and beta releases, there may be a bit of a “gold rush” mentality, as developers strive to be “the first on the block” to have a Compose-specific solution for some common problem, whether that is pager indicators or rich text editors or debug drawers. Hopefully, we will get that official API design guidance from Google before the rush really begins, as we will need that knowledge to design APIs that stand a chance of holding up as Compose continues to accelerate.