jetc.dev Newsletter Issue #95
Published: 2021-12-14
This week, we look at detecting touch events in a composable and removing jank from an animation. We poke at slot tables and the slot-based API, and we learn more about semantics. We visit another Navigation for Compose replacement library and a gist to turn us all into blockheads. And I ponder converting XML drawable resources into composables.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
How Do We Detect Touch Events Inside a Composable?
Many composables support the clickable()
modifier to detect simple click events.
However, what if you have a larger area and need to know the coordinates of touch
events within there? The pointerInput()
modifier and detectTapGestures()
are here
to help, as we see in this week’s highlighted Stack Overflow question.
How Do We Identify the Source of AnimatedContent Jank?
As we have seen a lot in this newsletter, excess recompositions is a major source
of jank and general poor performance. See how a very slight tweak is a composable
can dramatically improve the performance of an animation, in this week’s highlighted
Kotlinlang #compose
Slack thread!
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Video: Jake Wharton and Leland Richardson Answer Your Questions About Compose
The “Code with the Italians” team invited Google’s Leland Richardson
and Square's Block’s Jake Wharton to discuss Compose and its
internals, such as how the slot table system works.
Slotting In with Compose UI
Chris Banes provides an overview of the rationale and use of Compose’s slot-based API, where a composable takes other composables as parameters. The objective is to reduce the responsibility of any individual composable, delegating other responsibility to the supplied composables.
Videos: The Rest of droidcon London 2021
A couple of weeks ago I mentioned a pair of droidcon London 2021 presentations on Compose UI. At the time, the droidcon site was misbehaving, and I could not see the other presentations. That has since been fixed, and there were three other presentations on Compose UI:
- Julien Salvi: Exploring Jetpack Compose Canvas
- Dmytro Shuba: Testing Jetpack Compose UI
- Robert Williams: Backstack to the Future
Medium: Jetpack Compose — Optimize List Performance with Key
Pankaj Raj points out that using the right key in your LazyColumn()
or LazyRow()
can
make a lot of difference in the performance, particularly for mutable lists where items
might stay the same but change position within the list. Keys allow Compose to detect
those moves and avoid unnecessarily re-creating composables.
Video: Jetpack Compose: What’s The Fuss?
Omolara Adejuwon delivered a presentation at the DevFest Inspire event, reviewing the basics of Compose UI and what value it delivers to Android developers.
Slides: Semantics in Jetpack Compose
Bryan Herbst delivered a presentation on the role of semantics in Compose UI, both for
accessibility and for testing. Bryan published the slides, reviewing the use of
Modifier.semantics()
and how those semantics get mapped into AccessibilityNodeInfo
objects for use by TalkBack and similar accessibility services.
Medium: Jetpack Compose Enables JSON Defined View Layout
Elye returns, examining the basics of server-defined UI, where a Web service not only provides data but information about how to render that data.
Other Interesting Links
- SideEffects and Effects Handling in Jetpack Compose
- Making Complex UIs using Jetpack Compose. Building Leadership App
- Safe Compose arguments: An improved way to navigate in Jetpack Compose — Part 3
- Firebase, Login with Facebook in Jetpack Compose
- Advanced Form Operations in Jetpack Compose
- Medium: Creating a Toggle-able List Layout in Jetpack Compose!
- Medium: Network Connectivity on Modern Android Development with Jetpack Compose
- Medium: Playing with Jetpack Compose States & Flow
- Medium: Jetpack Compose Basics for Beginners
Resource Roundup
100% pure code!
GitHub: mobnetic / compose-advanced-preview
The team from Mobnetic created an AdvancedPreview()
composable, designed to wrap
a function for use with @Preview
. AdvancedPreview()
gives you more options for rendering
the preview, and more importantly makes the resulting image available outside of the IDE preview
pane (e.g., as screenshots for documentation).
GitHub: alphicc / Brick
Petr Shubin created another replacement for Navigation for Compose, with a wide array of features, including deeplink and arguments support, support for multiple modules, support for sheets/tabs/dialogs, and more.
Gist: zach-klippenstein / Blockify.kt
Google’s Zach Klippenstein created a set of composables that combine to wrap
some composable (say, an Image()
) around a cube (like, say,
the avatars for certain members of Block).
GitHub: copper-leaf / thistle
GitHub user Copper Leaf created a library for processing strings with inline markup.
The library then provides converters from that single markup syntax to Spannable
(for classic Views
), AnnotatedString
(for Compose UI), and ANSI codes (for terminal use).
Other Interesting Links
…And One More Thing
I will be tossing out ideas for tools and libraries from time to time here — this is one of those.
For a lot of developers, the “magic” tool would be something that could convert
a layout resource into composables. There have been some experiments to that effect.
However, that is a massive undertaking, even if we limit ourselves to framework and
Jetpack widgets. The sheer volume of view properties alone is daunting, let alone
working out how to map, say, the rules of TableLayout
into composables. It is doable,
but it is a lot of work. If you start adding in data binding and arbitrary third-party
views, and it gets even worse.
However, there seems to be a reasonable chunk of “low-hanging fruit” in the resource space that could be migrated to composables more easily. One would be XML-defined drawable resources.
Most of the XML drawables implement fairly simple rules:
-
LayerListDrawable
stacks N other drawables on the Z axis -
LevelListDrawable
chooses a drawable from a list of candidates based on a supplied “level” -
ClipDrawable
clips a drawable,RotateDrawable
rotates a drawable, etc. -
And so on
VectorDrawable
is complex, but given that we have SVG-to-composable tools,
there is a decent chance that creating a composable from a VectorDrawable
is not
that hard.
Are these “life altering” sorts of tools? No. But, for developers looking to move to a pure Compose UI setup, these tools could be useful options. They would be of particular interest to developers looking to use Compose outside of Android (e.g., Compose for Desktop), since Android resources are only useful for Android.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 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?!?
- 2024-11-19: Compose alphas! Compose Multiplatform patch! PaddingValues! Graphics layers! Swiping! Heatmaps! Navigation! And... why did we get a new production Compose BOM?!?