jetc.dev Newsletter Issue #119

Published: 2022-06-07

This week, we peek at beta03… and it feels like we are getting close to an RC!

Beyond that, we look at AlertDialog() and navigation. We explore what it took to wrap Google Maps in Compose and what it takes to get Twitter teams to develop composables. We examine design systems, slot APIs, and a few templates for helping get composables set up. And, I worry a bit about how libraries are supposed to deal with Compose Foundation and Compose Material and Compose Material3.

Beta Breakdown

Reviewing the release notes for the latest Jetpack Compose update!

1.2.0-beta03 of Compose shipped, and it mostly seems to be bug fixes.

We did get a new IntervalList/MutableIntervalList pair of classes, with an eye towards Lazy...()-style DSLs (item/items). It will be interesting to see if these classes move to Core or another Jetpack library, as they seem to be not very Compose-specific. We also got some improvements to keyboard handling, including support for injecting key events. But, with this limited amount of API changes, it feels like we will be moving to an RC in the coming weeks.

Wear Compose is also shipped a fresh beta, 1.0.0-beta03. ScalingLazyColumn() now works with @Preview-annotated composables. Also, a couple of compatibility notes:

  • ScalingLazyColumn now defaults to CenterHorizontally for horizontalAlignment — manually switch to Start if you need the old functionality

  • Be prepared for larger chips, as CompactChip has too small of a touch target, so it will get more padding in a future release

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Do We Use AlertDialog() with Navigation?

Navigation for Compose has a dialog() destination type. Compose UI has an AlertDialog() composable. Those are not designed to be used together, as we see in this week’s highlighted Stack Overflow question.

Where Did My setContent() Go?

TL;DR: If you are failing with NoSuchMethod: No Static method setContent, and you are using buildSrc, you may be missing a dependency. Learn more in this week’s highlighted Kotlinlang #compose Slack thread!

Composable Commentary

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

Medium: Diving Into Compose — Lessons Learned While Building Maps Compose

Google’s Chris Arriola describes the development of Maps Compose, the official Google option for embedding Google Maps into a Compose UI project. Chris explains the decision-making around the Maps Compose API, such as exposing Maps SDK classes, using coroutines for camera animations, using plain classes over data class, and more!

Video: Composing an API with Kotlin

Google’s Márton Braun delivered a presentation to Kotlin Dev Day Amsterdam 2022, exploring how the Compose API itself is implemented, with a focus on Kotlin idioms like extension functions, dedicated lambda receiver types (scopes), inline classes, and coroutines.

Slides: Branching out to Jetpack Compose

Chris Banes and Nacho López delivered a presentation on how Twitter is adopting Compose UI, including deciding whether to base your design system on Compose Foundation or Compose Material and developer support processes for massive development organizations.

Video: Implement your own design system with Jetpack Compose

François Blavoet delivered a presentation at Paris Android Makers 2022, covering what design systems are and how you create them in Compose UI, either based on Materal Design or from scratch. The slides are also available.

Medium: When Jetpack’s Glance met his fellow worker, Work Manager

Kasem SM looks at how to use WorkManager workers to update Glance-based app widgets. Kasem also weaves in Hilt and DataStore, the latter being used as the backing store for the content displayed in the app widgets.

Practical Compose Slot API example

We hear “slots” used a lot in Compose development. Slots are simply parameters to composables, where the parameters themselves are composables. This sounds simple, but it is a powerful concept. James Shvarts explores composables with slots and shows how it helps with reuse while still retaining Compose’s function-based form of composition, as opposed to the class-based inheritance style that you might use in classic View-based UIs.

Medium: Accordion Menu in Jepack Compose

Accordion-style expand-and-collapse container sets are a popular UI idiom. Emre Ozsahin examines how to implement one, using AnimatedVisibility() along with basic composables like Row(), Surface(), and LazyColumn().

Medium: Jetpack Compose Power Navigation

Debdutta Panda gives us a deep dive into Navigation for Compose, from adding the dependencies and basic setup through route arguments and getting results back from destinations.

Resource Roundup

100% pure code!

GitHub: webtoon / ReadMoreTextView

GitHub user webtoon set up a suite of “read more” UI elements, showing a truncated bit of text that expands when clicked. What makes this work interesting is that there are four separate implementations: for views, for Compose Foundation, for Compose Material, and for Compose Material3. I talk about this a bit more in “…And One More Thing”, later in the newsletter.

GitHub: dokar3 / sheets

GitHub user dokar3 brings us BottomSheet() that is a proper dialog rather than simply a composable that layers atop other composables in the same window. It also offers peek support and customizable animations for expand/collapse.

GitHub: mwolfson / jetpackTemplate

Mike Wolfson offers a project template that applies Compose Material3, Navigation for Compose, Detekt/ktlint integration, and more!

Jetpack Compose UI Architecture Templates

Roman Levinson created a plugin for IntelliJ IDEA / Android Studio that adds new templates to the “New” context menu, to create a stub “feature” (composable, viewmodel, etc.) and a new component (composable with Modifier parameter and @Preview setup).

…And One More Thing

The ReadMoreTextView family of libraries mentioned in the “Resource Roundup” section illustrate a problem with Compose UI: libraries wind up with lots of extra complexity, or they wind up “picking a side” when it comes to design system foundations.

In principle, the “read more” scenario is simple: show some text, then show replacement text when the original text is clicked upon. But, this requires three libraries and three sets of composables to cover just what’s in Compose UI:

  • One library offers BasicReadMoreText() as a wrapper around BasicText() from Compose Foundation

  • A separate library offers ReadMoreText() as a wrapper around BasicReadMoreText() that applies Compose Material styles

  • A third library offers ReadMoreText() as a wrapper around BasicReadMoreText() that applies Compose Material3 styles

That is a lot of overhead just to support everything from Compose UI. The reason why this is somewhat practical for this library is because the functionality is so simple. For a library with more complex widgets, the overhead may become too great, and the developer will pick one and call it good… and, most of the time, that seems to be Compose Material. This hampers projects that elect not to use Compose Material, as either they have far fewer libraries to reuse or they need to settle for pulling in Compose Material and the impacts that has on code completion, build times, etc.

This particular library would make for a fascinating case study for Google to explain how library developers should be approaching this problem.