jetc.dev Newsletter Issue #61
This week, we look at
@Preview, testing, and autofill. We explore customizing
MaterialTheme, work with animations (including 3D effects!),
and play a round of Asteroids.
Also, we listen to Leland and Romain talk for hours.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
@Preview is popular. The Jetpack
ViewModel is popular, particularly in existing,
pre-Compose projects. However, that does not mean that your
composable should take a
ViewModel as a parameter, as we see in this week’s
#compose Slack thread.
Posts, videos, and other new information related to Jetpack Compose!
Michel Onwordi wanted to write tests, but was hard-pressed to find information for blending Compose UI, Hilt for dependency injection, and testing. Fortunately, Michel not only worked it out but wrote up the findings for the rest of us!
Bryan Herbst returns, this time looking at autofill. Compose UI has hooks for autofill, but actually integrating autofill in a composable is up to the developer. Bryan shows how this is done, then shows how to wrap it up in a custom modifier to make integration much easier.
Gustav Karlsson answers a popular question: how do we create more colors?
MaterialTheme is great,
but it has a limited roster of color roles to choose from, based on the Material Design spec.
What if you want to have your theme offer colors for other roles, such as Gustav’s example
of a “warning” color to go along with the “error” color? In this post, we see how to create
a custom class for colors and
LocalColors fills the need.
Julien Salvi did a presentation for Dutch AUG on the
Canvas() API, including applying
animations to what you draw on the canvas. Julien also looks at drawing shapes for
composables more directly, using a
DrawScope. The slides for the presentation
are also available.
GuilhE takes a look at
Camera… not the one for taking pictures, but the one for
computing 3D transformations. In this case, GuilhE wants to animate a 3D effect of a timer on
Canvas(), with impressive results!
Other Interesting Links
- Jetpack Compose working with rotation animation
- Let’s Compose a Baby Monitor
- Mimicking IntelliJ IDEA’s splash screen with Jetpack Compose
- Animating in Jetpack Compose
- Bye XML, it was nice knowing you (pt. 1)
100% pure code!
You may have used
PagerSnapHelper to turn a
RecyclerView into a
UI. Aakar Shrestha brings us a similar
ComposePagerSnapHelper(), designed to turn
LazyRow() into a similar sort of pager.
Carson Holzheimer offers up a Kotlin/Multiplatform implementation of a macOS-style theme for Compose UI, for use either on creating desktop apps for macOS (or Linux or Windows), or for creating macOS-style UIs for Android… if you’re into that sort of thing. 😁
Other Interesting Links
- Gist: zach-klippenstein / SegmentedControl.kt
- GitHub: jisungbin / FancyBottomBar
- GitHub: Tlaster / NestedScrollView
…And One More Thing
Sometimes, when a new technology is introduced, it both solves problems and creates problems. This, in turn, requires solutions for those follow-on problems. Prior to the introduction of the car, we had no need for traffic signs and stoplights, for example.
One of the follow-on problems from Compose is going to be: where are we getting all of our composables from?
For example, this week’s highlighted Stack Overflow question
was about having some text with a circular background. The resulting composable
is not very long. However, for a lot of developers, using
layout() is going to be
“a bridge too far” in terms of complexity. They are going to want a
that they can just use.
Official Compose Material libraries will offer a bunch of stock composables. It is not
out of the question that they might provide some variation of
Text() that offers built-in
support for this sort of custom background shape. However, that is far from certain,
and there will be lots of UI patterns that will never make it into an official
Complex composables will get their own libraries — a bunch have been profiled in this newsletter. One imagines that there might be a few libraries will large collections of composables for common visual patterns, and text-in-a-circle might wind up in one of those. We will be able to manage those as well (or as poorly) as we have been managing other dependencies in the past. And, large composable collections add that much more to our build times, particularly for code shrinking, as tools try to figure out what is safe to remove.
But, on its own, text-in-a-circle does not warrant its own library. Pretty much any composable that fits in a Stack Overflow answer does not warrant its own library. Even if it were available in a library form, adding a library (and its own dependency resolution, etc.) is going to slow down build times.
The classic solution is to copy and paste the code into your app. This works, but it leads to maintainability problems: what happens when the Compose API changes in ways that breaks that code?
It will be interesting if somebody comes up with an innovative solution in this area, something that gives us a clear way to upgrade composables as needed (bug fixes, adopting newer Compose versions, etc.) while avoiding the pain points from lots of tiny libraries or massive composable libraries.
This problem is not unique to Compose: other types of code snippets have similar requirements. It is possible, though, that Compose triggers people to “scratch the itch” and come up with new approaches for managing these tiny-but-helpful bits of reusable code.
- 2023-11-21: Compose/Material3/Wear Compose updates! remember()! Adaptive layouts! Compose Multiplatform in 2024! @email@example.com on BasicTextField2()! Compose Multiplatform charts! And... is TV Compose in trouble?!?
- 2023-11-14: Compose Compiler! BasicTextField2()! @firstname.lastname@example.org and animations! Optimization! @email@example.com, JetBrains, and Fleet! JetBrains and plotting! And... we collapse?!?
- 2023-11-07: Compose Multiplatform! Chips in fields! Diffing! Custom fonts in Glance app widgets! Heatmaps! PIN input! And @firstname.lastname@example.org is in a bit of a haze?!?