Newsletter Issue #203

Published: 2024-02-20

This week, we look at the latest Compose Multiplatform RCs and explore the boundaries of State. We explore nested scrolling, lambda memoization, and Amper. And we put the hammer down on our use of Material3 composables inside of Android Studio.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

We got two Compose Multiplatform RCs back to back! 1.6.0-rc01 and 1.6.0-rc02 fix a variety of bugs across the non-Android platforms. Note that the RCs are not binary-compatible with the betas, so if you get Could not find "org.jetbrains.compose.annotation-internal:annotation" errors, upgrade your libraries to versions that support the Compose Multiplatform 1.6.0 RCs.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can We Have Dynamic Tabs?

Sometimes, a ScrollableTabRow() has a fixed number of tabs. Other times, it can change on the fly, such as getting a fresh set of tabs from a server. The beauty of much of Compose is that reacting to changing data is no different for a row of tabs than it is for anything else: use State. Learn more in this week’s highlighted Stack Overflow question.

How Can We Expose State Without Allowing Mutation?

You may have a viewmodel or similar object that holds a MutableStateList. In that case, you probably want composables to have access to the list without the ability to mutate the contents. The crazy-simple answer: expose it as a List. Learn more in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

Posts, videos, and other new information related to Jetpack Compose!

Medium: Understanding Nested Scrolling in Jetpack Compose

From collapsing app bars to scrollable content in bottom sheets, nested scrolling is key to many user experiences. Google’s Levi Albuquerque explores how to implement this from scratch, powered by the nestedScroll() modifier, for cases where you cannot get it “out of the box”.

Reddit: Leland Richardson on Lambda Memoization

In an extensive comment to a Reddit post about unstable lambda parameters, Google’s Leland Richardson dives deeply into the issue, from explaining how “unstable lambda” is somewhat mis-labeled, to how the new “strong skipping” should help alleviate the problem most of the time.

Using Amper with Fleet in a Kotlin/Compose Multiplatform project

John O’Reilly is back, looking at building a Compose Multiplatform app using the Fleet IDE and Amper, JetBrains’ new project configuration tool. Amper sits atop Gradle and uses YAML files for things like dependencies and project settings.

Medium: Alignment with Jetpack Compose

Diego Ramírez needed fine-grained control over things like text baselines. Diego shows us what an AlignmentLine is, how to create a custom one (e.g., CenterAlignmentLine), and how to use that to align text and icons in a Row().

Medium: Building a simple Web Application with Compose Multiplatform using Decompose

Compose Multiplatform discussions tend to focus on iOS and the desktop, leaving out the Web. Jorge Luis Castro Medina dives into that latter topic, looking at what it takes to create a Web target and use Decompose for navigation between screens.

Medium: Avoid Auto-Resizing on Re-compose

In the View system, we could have an invisible view: one that takes up space but does not render any pixels. This would allow us to hide some widget while not having adjacent widgets resize take up the “empty” space. Medium user Itsuki explores how to implement the same sort of resize-avoidance by using the onGloballyPositioned() modifier to save the initial size, via remember(), for later reuse on recomposition.

Medium: Getting the native iOS look & feel in your Compose Multiplatform app

One of the downsides of Compose Multiplatform is that, by default, you will wind up with Material Design widgets on other platforms. On the desktop or Web that can be fine, but it will look odd on iOS. Jacob Ras reviews Compose Cupertino, specifically cupertino-adaptive, which gives you a Material look on Android and an iOS look on iOS.

Medium: Jetpack Compose Clip or Cut a Composable with Custom Image Shape

Ban Markovic examines how you can clip a composable, such as a progress indicator box, using a custom shape. Ban’s approach leverages the drawWithContent() modifier to blend the custom shape (in the form of an ImageBitmap) with the content to be clipped.

Resource Roundup

100% pure code!

GitHub: Ivy-Apps / compose-hammer

The Ivy Apps team built an Android Studio plugin with code generators and a tool window to help you employ Material3 components and employ standard Compose structures (e.g., LaunchedEffect()).

GitHub: kosenda / AutoSizeTable

GitHub user kosenda supplies us with an AutoSizeTable() that implements a 2D scrolling grid with automatic sizing of columns based on their data.