jetc.dev 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.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-12-10: A Compose Multiplatform alpha! Hot reload! Presentation! Sprites! Calendars!
- 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?!?