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.
Other Interesting Links
- Medium: Jetpack Compose with Lifecycle-Aware Composables
- Medium: Two-way data binding in Jetpack Compose
- Medium: Easy Android ListView Pagination using Jetpack Compose
- Medium: Animated Placeholder with Jetpack Compose
- Medium: Using compose destinations
- Understanding Composition and Side Effects
- Medium: Jetpack Compose: everything you need to know to get started
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:
-
Android 13 seems to have some new TV-related APIs, suggesting that Android TV might continue getting OS version updates
-
There are rumors of new hardware (and, yes, a “Chromecast with Google TV” is an Android TV device, because branding is hard)
However, Compose UI support for Android TV still seems to be a work in progress:
-
The roadmap mentions “Trackpad/D-Pad navigation” as “In Focus”, so it is not yet “Done”
-
There is no mention of “TV” or “leanback” in the roadmap, where “leanback” is Google’s term for TV-centric user interfaces
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!
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-10-01: Lazy grids! Focus! @colinmarsch@androiddev.social on CMP accessibility! @skydoves@androiddev.social on Landscapist! @sinasamaki@androiddev.social on Slider()! And... what is it?!?
- 2024-09-24: A Compose security fix and a new alpha! clipToBounds()! Localization! offset()! @skydoves@androiddev.social on server-defined UI! Bottom sheets! And... someone set us up *3* BOMs?!?
- 2024-09-17: Compose 1.7.1 and Compose Multiplatform 1.7.0-beta02! Flow layouts! TV Compose! SharedBounds! Image cropping! And... why does remember() not seem always to remember?!?