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.

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.

…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:

  1. 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

  2. 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 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.