jetc.dev Newsletter Issue #61
Published: 2021-04-20
This week, we look at @Preview
, testing, and autofill. We explore customizing
and extending 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!
Create Text with Circle Background
Having text with a circle as a background is a fairly common UI element. Creating one in Compose UI is doable but surprisingly annoying, as we see in this week’s highlighted Stack Overflow thread.
@Preview and a ViewModel
@Preview
is popular. The Jetpack ViewModel
is popular, particularly in existing,
pre-Compose projects. However, that does not mean that your @Preview
-annotated
composable should take a ViewModel
as a parameter, as we see in this week’s
Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Podcast: Composed Leek
The Android Leaks podcast hosted Google’s Leland Richardson and Romain Guy for a
2.5 hour session, on topics ranging from CompositionLocal
and MutableState
to coroutines and Compose for Desktop.
Writing An Integration Test With Jetpack Compose and Dagger Hilt
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!
Handling Back Presses in Jetpack Compose
Paweł Gajda takes a look at Navigation for Compose, specifically on how to find out when the user uses back or up navigation, in case you need to take some specific steps at those points.
Autofill with Jetpack Compose
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.
Android Material Theming in Jetpack Compose
Satya Pavan Kantamani provides us with a basic overview of using and customizing
MaterialTheme
, including colors, typography, and more.
Extending the Jetpack Compose Material Theme with More Colors
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.
Animate with Jetpack Compose: Animate as State and Animation Specs
Andrew Khrystian wrote about Compose’s animation APIs, including the animate...AsState()
functions and various types of AnimationSpec
.
Video: Introducing Compose for Desktop
JetBrains’ Sebastian Aigner delivered a presentation for Brighton Kotlin, providing a brief overview of Compose, then taking a peek at Compose for Desktop and reviewing its capabilities.
Video: Exploring Jetpack Compose Canvas
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.
Compose, Camera and Canvas
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
a Compose 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)
Resource Roundup
100% pure code!
GitHub: aakarshrestha / compose-pager-snap-helper
You may have used PagerSnapHelper
to turn a RecyclerView
into a ViewPager
-like
UI. Aakar Shrestha brings us a similar ComposePagerSnapHelper()
, designed to turn
a LazyRow()
into a similar sort of pager.
GitHub: Chozzle / compose-macos-theme
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. 😁
GitHub: SebastianAigner/asteroids-compose-for-desktop
Last week, it was Tetris. This week, we go back further in time, with JetBrains’ Sebastian Aigner releasing an implementation of the classic video game Asteroids, built for Compose for Desktop.
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 CircleText()
composable
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
library.
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.
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?!?