jetc.dev Newsletter Issue #118
Published: 2022-05-31
This week, we get lazy, exploring lazy grids and the visibility of items in lazy collections.
Beyond that, we see how to implement custom pull-to-refresh animations and sensor-based parallax effects. We try to make sense of Compose compiler metrics output and add a color âeyedropperâ to our apps. And I double down on the importance of setting up a design system⌠after which I talk a bit about how this newsletter gets assembled.
One Off the Stack, One Off the Slack
Youâve got questions. Thatâs understandable!
How Do We Know the Visible Lazy Items?
Sometimes, you need to be able to react as users scroll a LazyColumn()
or
LazyRow()
, to be able to take actions as composables come and go from the
screen. LazyListState
has a layoutInfo
property for this purpose, as we
see in this weekâs highlighted Stack Overflow question.
Why Does fillMaxWidth() Not Work as a Default Value?
It seems straightforward: use Modifier.fillMaxWidth()
as the default value
for the modifier
parameter in a composable. That may not work, though â
see how to work around it in this weekâs highlighted Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Lazy Grid layouts in Compose
James Shvarts keeps churning out Compose UI posts! This time, James looks at
implementations of LazyVerticalGrid()
, LazyHorizontalGrid()
, and the GridCells
interface, for implementing grids in Compose UI.
Medium: Custom Pull to Refresh in Jetpack Compose
Medium user sinasamaki is back, looking at the pull-to-refresh UI pattern and how
to implement a custom animation for one in Compose UI, based on Accompanistâs
SwipeToRefresh()
composable.
Medium: Parallax Effect with SensorManager using Jetpack Compose
While parallax effects are most often associated with swiping and scrolling,
other forms of input can be used as well, such as the physical movement of the
device. Suraj Sau shows us how to implement that, via SensorManager
and a Channel
to supply state changes for rendering the UI.
Medium: Classic Snake Game with Jetpack Compose
The âSnake gameâ has been around for decades. Mukesh Solanki offers up an implementation in Compose UI, exploring how the game engine is implemented and how to create an on-screen D-pad for controlling the snakeâs movements.
Other Interesting Links
- Medium: Jetpack Compose under the hood: Touch Events
- Animated Pixie Dust Cursor and more
- Medium: Updating UI using state management in Jetpack compose
- Medium: Adding native code to an Empty Compose Activity project
- Medium: Using Android Jetpack Compose
Resource Roundup
100% pure code!
GitHub: PatilShreyas / compose-report-to-html
Shreyas Patil is back, this time with a command line utility to convert Compose compiler metrics output from CSV/JSON/TXT into formatted HTML for easier reading by developers, complete with color coding.
GitHub: germainkevinbusiness / CollapsingTopBarCompose
Germain Kevin offers us a CollapsingTopBar()
, designed for use as the topBar
of a Scaffold()
, that implements a few possible collapsing patterns.
GitHub: SmartToolFactory / Compose-Color-Detector
The SmartToolFactory team is back at it, this time with a couple of composables for implementing âeyedropperâ-style tools for picking colors from an image or the screen.
Other Interesting Links
- GitHub: fengdai / compose-media (ExoPlayer composables)
- GitHub: ILIYANGERMANOV / ivy-frp (functional reactive programming framework)
- GitHub: thinkupsoft / onboarding-library-android (showcase-style intro composable)
- GitHub: ferhatwi / crop (image cropper)
âŚAnd One More Thing
When you get started with Compose UI, code organization tends to âtake a back seatâ to just getting stuff working. Compose takes a lot of getting used to, and simply having working code is a significant success point.
However, as you gain experience, and particularly if you work on professionally-designed apps, Compose UI lends itself to a two-tier approach:
-
Building a design system: creating the composables that represent individual UI elements (labels, buttons, fields, etc.), styled in accordance with what the designs call for and with an eye towards reuse
-
Assembling screens, bottom sheets, and similar larger UI constructs with the elements from the design system
Not only does this help with code organization and minimizing duplicate composables, but it helps structure ongoing conversations with the designers. For example, suppose that you get a new design for a new screen that contains a label that does not match any existing element from your design system. You can ask the designers:
-
Is this variation intentional, or does it represent a mistake in the design? (hey, it happensâŚ)
-
Is this actually one of the existing elements that has changed? If so, do all existing uses of that element change as well?
-
If this element is totally new, is this variation a âone offâ, or is it likely to appear again in the future?
These sorts of questions can help guide the designers towards thinking in terms of reuse and a structured design system. At minimum, though, these questions can help you determine how best to accommodate this new element within your library of composables, to guide âfuture youâ for applying it if it shows up in later designs.
Addendum: How the Sausage Gets Made
Every weekend, I spend a few hours assembling the newsletter issue that comes out on Tuesdays (my time).
The articles and posts that I link to come from ones that I encounter during the week,
plus some specific searches (e.g., Medium). If you would like to have your post
be considered, besides reaching out to me directly, just publicize the post in
a typical spot (e.g., #JetpackCompose
hashtag in Twitter), and I am likely to encounter
it. The same holds true for the GitHub repositories and other code resources that
I link to.
For articles and posts, mostly I review them to see if they are readable in English and are of reasonable length. Posts that are very short, or add little value to some link or code dump, usually do not âmake the cutâ for an issue. However, I rarely judge posts based on some concept of correctness, as I am not an arbiter of what is or is not good in the world of Compose. Besides, âwhat is or is not goodâ in Android overall changes over time.
Note that I have cut back on linking to videos. Videos are wonderful, but they are very tedious for me to review for this newsletter. So, recently I have been limiting videos to:
-
Official ones from Google
-
Ones containing Googlers (or prominent ex-Googlers)
-
Conference presentations
For GitHub repositories, mostly I focus on whether or not the project has a decent
README
, explaining what the repository contains and how it might be used. Those
lacking adequate documentation usually get ignored. However, I do
not do a code review of those repositories, or of any sample projects referenced by
an article or post. Most of those repositories probably contain some bad code, because
every repository contains some bad code.
In short, links are not endorsements. My role is to highlight what is new.
If you see that I linked to an article, post, repository, etc. that you dislike, talk to the author of the article, post, repository, etc. Try to help the author improve their work. If you want to complain to me about things that I wrote, that is perfectly reasonable and you are welcome to do so.
I run this newsletter as a public service. This is not part of my day job,
as CommonsWare is now âa hobby with a logoâ, and my current employer is not involved
with this. There are no ads. There is no subscription
fee. I do not participate in referral programs. Heck, if you get the newsletter
through the main jetc.dev
site, there should be zero
tracking cookies. I get no immediate benefit from this newsletter other than a
vague sense that I am being useful.
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?!?