jetc.dev 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.
Other Interesting Links
- Basics of Jetpack Compose - 1
- Medium: Android Symphony: A UX Melody with Tooltips, Popups, and Dialogs
- Medium: Animated Border Using Jetpack Compose
- Medium: Checking out MVC 📐Architecture Pattern in Android Jetpack Compose
- Medium: Effortless Loading Screen with State Flows and Jetpack Compose — Just 4 Easy Steps
- Medium: From Concept to Code: Crafting an Android Audio Book App with Jetpack Compose and MVI (P-3)
- Medium: Implementing Bottom Sheets in M3 with Navigation Bars Padding Compliance
- Medium: Make Component Below Lazy(Column/Row) in Jetpack Compose
- Medium: Popup with Navigation
- Medium: Prevent accidental swipe while scrolling in LazyColumn
- Medium: Recomposition in Jetpack Compose
- Medium: Using Text in Jetpack Compose
- Medium: Working With Date Picker in Jetpack Compose
- Neumorphism in Jetpack Compose
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.
Other Interesting Links
- GitHub: ThomasBernard03 / Composents (buttons and nav bar)
- GitHub: what3words / w3w-android-design-library (Material3-based design system)
- GitHub: zekierciyas / survey-compose (survey form and questions)
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?!?