jetc.dev Newsletter Issue #217
Published: 2024-06-04
We got new betas for Compose and Wear Compose, as the drive for stable releases for both continues apace!
Beyond that, we see an interesting use of decorationBox
to replace VisualTransformation
for structured fields, as well as how to use Koin within Compose Multiplatform environments.
We look at iOS/Compose interop and design systems. And we examine an MVI framework and a
discrete seek bar implementation, along with a new stable Molecule 2.0.0
release.
Ooooo… What Did We Get?
Reviewing the release notes for the latest Jetpack Compose update!
Compose 1.7.0-beta02
is out, including a new prefetch API for lazy grids, some renamed
APIs, and some bug fixes.
Compose Material3 1.3.0-beta02
has a few more changes, including:
-
Converting
TooltipScope
to asealed interface
-
Adding elevation support to the
pullToRefreshIndicator()
modifier -
Adding
maskClip
andmaskBorder
modifiers toCarouselItemScope
Compose Material3 Adaptive is up to 1.0.0-beta02
, with just some minor changes.
Wear Compose 1.4.0-beta02
was released with some screen reader-related fixes.
And in Compose-adjacent libraries, we got:
androidx.fragment:fragment-compose:1.8.0-rc01
androidx.lifecycle:lifecycle-runtime-compose:2.8.1
androidx.lifecycle:lifecycle-runtime-compose-android:2.8.1
androidx.lifecycle:lifecycle-runtime-compose-desktop:2.8.1
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.1
androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.1
androidx.lifecycle:lifecycle-viewmodel-compose-desktop:2.8.1
androidx.navigation:navigation-compose:2.8.0-beta02
androidx.navigation:navigation-fragment-compose:2.8.0-beta02
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
How Do I Fix a Concurrent-Change Crash?
Getting an IllegalStateException
with the message Unsupported concurrent change during composition
is going to ruin your day. This comes when you try modifying some MutableState
both inside
and outside of a composition. Learn more in this week’s highlighted Stack Overflow question,
including an answer from Google’s Chuck Jazdzewski.
How Can I Use a Gradient for a Stroke?
If you want a gradient sweep for the stroke of something like a circle, you can convert the
stroke to a Path
, then draw the path with a sweepGradient
brush, as Google’s Romain Guy
notes in this week’s highlighted Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Medium: Creating Unique TextFields in Android with Jetpack Compose and DecorationBox
We have seen a lot of posts that use VisualTransformation
to handle structured text input,
such as adding hyphens between phone number segments. Medium user Nurattin explores an
alternative approach, leveraging the decorationBox
slot parameter to have a BasicTextField()
leverage a mix of static text and editable segments.
Medium: Unlock the Power of State Hoisting in Jetpack Compose
Teni Gada explores what we mean by “state hoisting” and how we apply it for UI and state logic, when to use dedicated state holder classes versus viewmodels, and more.
Medium: Jetpack Compose: System UI Compatibility and Immersive Status Bar
Medium user ZhangKe looks at how to extend our UI to be behind the status and navigation bars
via enableEdgeToEdge()
, how to leverage WindowInsets
to know how big those bars are,
how Scaffold()
hides inset complexity from us, etc.
Medium: Injecting your Compose applications with Koin — From Android to Multiplatform
Arnaud Giuliani describes how to use Koin for dependency inversion with Compose, including how to work with previews, how to support Compose Multiplatform, using isolated contexts for SDKs/white-label apps, and more.
Page Flip animation in Jetpack Compose
Sinasamaki demonstrates how to reproduce Flipboard’s flipping page animation in Compose UI,
in the form of a FlipPager()
composable that supports horizontal and vertical flipping,
leveraging bitmap recording to animate a bitmap instead of the actual composable content.
Effective Map Composables: Non-Draggable Markers
Uli Bubenheimer is exploring Maps for Compose, this time looking at a new non-draggable form of marker that a future Maps for Compose release will support.
Medium: Android/JetpackCompose: Component Sizing, Layout and Two Views Same Size 2 Ways
Medium member Itsuki looks at two different ways to determine the size and position of a
component, with an eye towards making changes to those aspects. Itsuki first tries
the onGloballyPositioned()
modifier, then turns to a Layout()
wrapper in the hopes
of boosting performance.
Medium: Android Development: Building a Custom Design System with Jetpack Compose
Alexandros Damianakis writes about how we can customize a Compose Material3 theme, including colors, typography, and shapes. Alexandros also shows how to extend the concept of a Material3 theme to include things like custom sizing rules.
Medium: Bringing Together: Jetpack Compose and Native iOS Components
Chetansinh Rajput looks at iOS native view interoperability with Compose for iOS, including rendering composables inside of SwiftUI/UIKit views and having UIKit components be part of your composables.
Other Interesting Links
- Jetpack Compose -Difference between mutableStateOf() and derivedStateOf()
- Leverage the essentials: Jetpack Compose best practices
- Medium: Android/Kotlin/Jetpack Compose: Screen Size 2 ways and fillMaxSize pitfall!
- Medium: Compose Chronicles: Beyond the UI — The Hidden World of SideEffects
- Medium: ConstraintLayout in Compose
- Medium: Crafting Custom 3D Dialog Animation in Jetpack Compose
- Medium: Creating an Animated Arrow Pointer in Jetpack Compose
- Medium: Developing for Foldable and Multi-Screen Devices with Jetpack Compose
- Medium: How To Use Shared Element Transitions in Jetpack Compose
- Medium: Mastering Custom Graphics in Jetpack Compose: Building Unique Progress Indicators with Canvas
- Medium: Migrating from XML to Jetpack Compose in Android: A Seamless Transition
- Medium: Scrollable TabRow Using Jetpack Compose — Material3
Resource Roundup
100% pure code!
GitHub: localhostov / icons
Alexander Localhostov (whose IP address may or may not be 127.0.0.1
) released a Compose
Multiplatform icon pack, with 498 straight and rounded icons. Preview those icons here!
GitHub: ChainTechNetwork / sdp-ssp-compose-multiplatform
Medium user ssvaghasiya published a Compose Multiplatform library offering implementations of SDP (screen dp
) and
SSP (screen sp
) units that scale with screen size. See this Medium post
for more.
GitHub: ikarenkov / Modo
Karenkov Igor has released an MVI-style Compose UI app framework with integrated navigation support.
GitHub: jongmin1217 / ComposeStepSlider
GitHub user jongmin1217 brings us a highly configurable discrete seek bar implementation, to allow the user to select one of a range of values by sliding a thumb along a track. See this Medium post for more.
GitHub: FrankieShao / PullToRefresh-Compose
GitHub user FrankieShao brings us a pull-to-refresh implementation that works for LazyRow()
as well as LazyColumn()
. It also offers support for custom loading indicators.
Notable Releases
Horologist is now up to 0.6.13
,
connecting to beta versions of Wear Compose and Compose, plus offering improvements to layout
behavior on larger Wear OS devices.
CashApp’s molecule reached a milestone 2.0.0
release.
It adds support for Kotlin 2.0.0 and replaces their Gradle plugin with JetBrains’, which requires
you to add a runtime dependency for any module using molecule code.
Circuit — Slack’s opinionated framework for constructing Compose-based UIs —
now has a 0.21.0
release with support
for Compose for Web/Wasm.
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?!?