jetc.dev Newsletter Issue #112

Published: 2022-04-19

This week, we look at snapping LazyRow() composables and whether widgets should be stateful. We spend time on performance analysis, including the recently-added Compose compiler metrics reports. We look at animations, both how to set them up and how to test them. SmartToolFactory has a couple of new libraries, so we check those out. And I continue to wonder when Compose will be on TV.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Do I Snap a LazyRow()?

A LazyRow(), like a LazyColumn(), allows the user to scroll to arbitrary points. However, sometimes you may want “snapping” behavior, such as always having an item be centered or always having an item be aligned with the start edge. Learn about how a couple of libraries give you some options for this, in this week’s highlighted Stack Overflow question.

Is It OK to Have Stateful Widgets?

By default, Compose UI widgets are stateless, with state being maintained in separate objects from the composables that render them. But, is this the only option? Learn more in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Medium: Migrating Architecture Blueprints to Jetpack Compose

Google’s Manuel Vivo describes what it took to migrate Google’s architecture samples to use Compose UI instead of the classic View system. They left the viewmodels alone, so their samples show LiveData instead of Flow for the reactive data streams. The post covers developing the plans, key steps in the implementation, and a list of problems that they encountered.

Composable metrics

Chris Banes brings us a deep dive into the Compose compiler plugin’s new ability to output reports about the contents of your composables. Chris helps you determine how best to convert that data into actionable steps to improve the performance of your Compose UI interfaces.

How can I debug recompositions in Jetpack Compose?

Vinay Gaba is back, looking at various ways to detect overcomposing: where your composables get recomposed more frequently than is warranted. Vinay looks at the recomposeHighlighter() modifier, the same Compose compiler metrics that Chris Banes reviewed in the preceding newsletter item, and good old-fashioned Log statements.

Medium: Animate on a Path with Android Jetpack Compose UI

Phil Boyd explores the steps it takes to have some composable (such as an Image()) animate along some pre-determined but arbitrary path. Phil looks at having dependent animations (such as having the Y position be derived from the X position), as well as how to rotate the moving composable based upon the path position. Warning: this post contains trigonometry.

Medium: Creating an animated selector in Jetpack Compose

Francesc Vilarino Guell returns, this time examining selectors, such as the chosen item among a row of radio-button-style toggle buttons. Francesc wanted the selection indicator to slide from the previous selection to the newly-selected item. This resulted in a MultiSelector() composable based on a Layout(), to wrap up all of the animation and clipping complexity.

Jetpack Compose: Testing animations

With all these animations, it seems like we might want to test them. Alex Zhukovich has our back, with a post exploring how to set up screenshot testing with Compose’s virtual clock and Shot to create test cases for animations.

Medium: Matured Constraint Layout in Jetpack Compose

Siva Ganesh Kantamani looks at the Compose UI edition of ConstraintLayout() and how its DSL works to let you create complex layouts concisely.

Resource Roundup

100% pure code!

GitHub: racra / smooth-corner-rect-android-compose

Rodrigo Alves brings us an AbsoluteSmoothCornerShape class that can be used to create squircles, super-ellipses, and similar shapes, used to crop a Surface() or other composables.

GitHub: SmartToolFactory / Compose-Extended-Gestures

The SmartToolFactory team has been on a roll recently, with a bunch of interesting libraries. This time, they offer up some modifiers to help simplify gesture detection involving multiple pointers.

GitHub: SmartToolFactory / Compose-Screenshot

Did I mention that SmartToolFactory has been on a roll? They have also released a ScreenshotBox() composable and corresponding ScreenshotState. These combine to let you capture composables as bitmaps, either on a one-time basis or periodically (for collecting a series of bitmaps).

GitHub: overpas / svg-to-compose-intellij

Pavel Shurmilov has wrapped Gabriel Souza’s svg-to-compose tool into a plugin that works with IntelliJ and Android Studio. This lets you convert one (or several!) SVG images to corresponding composables.

Detekt Suppressors

Detekt is a static analysis tool to help you identify quality problems with your app (code smells, etc.). However, false positives can be a bit of a problem. To help with this, Detekt offers suppression rules, to teach Detekt situations where problems should be ignored. One such rule is an annotation rule, and you can use that to teach Detekt to ignore your Compose UI @Preview-annotated functions and not complain about those. That technique can be useful if you use dedicated @Preview functions (for code that will not be used in production), instead of putting @Preview on real composables that your users wind up seeing.

…And One More Thing

Android TV is getting some love in 2022:

However, Compose UI support for Android TV still seems to be a work in progress:

That unfortunately overlaps with stymied progress on the classic View-based Leanback libraries, which have not seen a new alpha in five months.

It would be good to know whether Google intends on having a Compose UI equivalent of Leanback or whether Android TV developers need to put their energies towards some independent implementation of the concept. Google’s Chris Sinco indicated that discussions were taking place back in February, presumably around official Compose support for TV apps. But, other than experiments like this TV launcher app, I am not seeing a lot of community activity in this space either.

Hopefully, we will get some clarity in this area in the coming weeks. After all, Google I|O 2022 is coming soon!