jetc.dev Newsletter Issue #69
Published: 2021-06-15
This week, we look at creating composables for a Sudoku grid, internationalization concerns, and scaleable animations. We stagger around lazily with a grid, and we create a Chrome extension using Compose for Web. Plus, we spend a lot of time on navigation, including a look at why everybody seems cranky about that subject.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
fillViewPort
Equivalent for Column()
Finding the Compose UI equivalent of a classic View
solution is sometimes a problem…
particularly when the solution depends on a specific order of modifiers. In this case,
building a Column()
that both scrolls yet honors a Spacer()
to have a bottom-aligned
element can be tricky, as we see in this week’s highlighted Stack Overflow question.
MutableState
vs. MutableStateFlow
Do we use Compose’s MutableState
? Do we use coroutines’ MutableStateFlow
?
Both? Neither?!? Google’s Adam Powell tries to give us some guidance in this
week’s highlighted Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Navigating in Jetpack Compose
Navigation in Compose is a popular topic.
In this post, Jossi Wolf explores the basics of working with Navigation for Compose, including the details of how Navigation for Compose layers atop the existing Jetpack Navigation library. Jossi also looks at navigation arguments, separating navigation from composables, and more!
Safe & Easy Navigation with Jetpack Compose
Did I mention that navigation in Compose is a popular topic?
Here, Roman Levinzon also looks at Navigation for Compose, with a focus on arguments. However,
Roman was unsatisfied with the state of arguments support and elected to create
a safe-routing
library that supplies
a annotation processor to code-generate a lot of the navigation boilerplate around
arguments.
The Story of My First A-ha Moment with Jetpack Compose
Adib Faramarzi wrote a Sudoku app in Compose UI and wrote up the experience, including crafting stateless composables, creating decorators through wrapper composables, and applying modifiers in custom composables.
Video: Fixing Bugs with TDD in Jetpack Compose
Adam McNeilly returns, this time with a long screencast about a bug. Along the way, Adam writes tests to demonstrate the bug, fixes the bug, and more!
Following the Way of Migration to Jetpack Compose
Alexander Berezhnoi offers some opinions on migrating a traditional Android app
to Compose UI and Compose Material. Alexander makes the case for when (and when not)
to migration, whether to use ComposeView
or AndroidView()
, and how to work around
various issues, such as the lack of menu and preference APIs.
A Deep Dive Into Internationalizing Jetpack Compose Android Apps
The team at Phrase wrote a massive post on internationalization in Compose UI, looking at
how Compose integrates with classic Android i18n solutions, such as string and plural resources, NumberFormat
,
and DateTimeFormatter
. The post also looks at how to flexibly handle whitespace and widget sizes
in Compose UI, to handle translated text of varying lengths.
Video: Exploring Canvas API, Jetpack Compose
Chetan Gupta delivered a presentation for DSC University of Ibadan, covering the use
of a Canvas()
, including animations, with a focus on game development.
Jetpack Compose Animations in Real Time
Halil Ozercan is back, with another look at animations and the Canvas()
API. However,
this post focuses more on the state management surrounding the elements to be animated,
and how to tie changes in that state to frame drawing rates, so the animation can scale
its complexity with the capabilities of the device and its display.
Compose: List / Detail – Testing part 1
Mark Allison continues his exploration of Compose UI and the list/detail pattern. This time,
Mark starts trying to test the composables, including how to revise composables to be more
testable and how to use createAndroidComposeRule()
to write Compose UI instrumented tests.
Other Interesting Links
Resource Roundup
100% pure code!
Gist: bmc08gt / StaggeredVerticalGrid.kt
Brandon McAnsh was looking for a lazy staggered vertical grid in Compose UI, came up empty, and wrote one!
Gist: JustJerem / CircularProgressIndicator.kt
GitHub user Jérémie G. brings us another progress indicator, this one transforming into an icon once you reach the maximum progress value.
GitHub: hfhbd / routing-compose
Routing requests to composables is going to be a bit different in Compose for Web than in the Android or desktop counterparts. Navigation for Compose is Android-specific and is of little use with Compose for Web. So, Philip Wedemann is experimenting with creating a composable router designed from the ground up for use with Compose for Web.
GitHub: theapache64 / compose-chrome-extension-template
GitHub user theapache64 continues creating tools and templates for Compose targets. This time around, we get a template for creating a Chrome extension using Compose for Web.
…And One More Thing
It feels like navigation is going to be a problem for a while.
Originally, when a handful of navigation libraries were developed by the community, my expectation was that once the official Navigation for Compose was released, that would become the de facto choice for Compose UI developers. That has not seemed to be the case: between wrappers around Navigation for Compose or replacements for it, we are still “in the woods” trying to settle on a primary option.
Some developers are not happy with Navigation for Compose, for various reasons:
-
In some cases, it is missing features, such as transition animations. For many developers, those animations are “nice to haves”, but for others, they are essential. And, if Navigation for Compose does not (yet) offer them, developers will need to roll their own solution. While this specific problem is on the docket to be addressed in the coming months, other missing features might not be.
-
In some cases, it is confusion surrounding existing features. Some Google engineers say you should only use identifiers in navigation routes for arguments. The documentation indicates otherwise.
-
In some cases, it is a discrepancy between Google and a portion of the developer ecosystem. Navigation for Compose is tied fairly tightly to Android. That is fine if you intend to use Compose UI purely for Android app development. If you wish to support other targets, such as Compose for Desktop, you need an Android-free navigation solution. Navigation for Compose is an offshoot of Jetpack’s Navigation library, and that has always been for Android… yet it feels like there was a missed opportunity here.
-
In some cases, it is history. Jetpack’s Navigation component has its fans and its detractors. Those who disliked it in classic Android app development are unlikely to be excited by using it with Compose UI.
Some might wonder whether we need a single popular navigation solution. Indeed, we might be able to live with lots of solutions for a while. Perhaps one solution will rise above the rest with time — whether that solution is Navigation for Compose, some other supported option (e.g., from JetBrains), or a community solution.
The challenge is in transfer of knowledge from project to project. Learning the API
surface of a project’s design system will be a big enough problem. Adding a bespoke or
unusual navigation framework adds to the learning curve. My fear is that we wind up
in a situation where two projects share few directly-used APIs beyond the @Composable
annotation
and a handful of core elements like remember()
and mutableStateOf<>()
.
If this sort of thing concerns you, make sure that your projects have good documentation. Newcomers to the project need ways to blend their existing Compose knowledge with the specifics of how things get done in your project, including how you send your users from screen to screen within your app.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-12-10: A Compose Multiplatform alpha! Hot reload! Presentation! Sprites! Calendars!
- 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?!?