jetc.dev Newsletter Issue #152
Published: 2023-02-07
This week, we look at tinted vector drawables and TextField()
state. We explore
a DropdownMenu()
replacement, SnapshotMutationPolicy
, and a custom
collapsible app bar implementation. We get a sneak peek at some Slack Lint checks,
along with runtime permission helper code. And,
ask not for whom the bell tolls,
it tolls for databinding.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
Why Is My Vector Drawable Color Being Ignored?
A vector drawable can use android:fillColor
to specify the colors for its paths.
However, the Icon()
composable ignores those and renders the paths in black by
default. See how to use the tint
parameter to eliminate that behavior in this
week’s highlighted Stack Overflow question.
How Do We Synchronously Update TextField() State?
An important Medium post
from Alejandra Stamato last year pointed out issues in updating TextField()
state asynchronously. See a few techniques for doing it synchronously in this
week’s highlighted Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Medium: Fundamentals of Compose layouts and modifiers
Simona Stojanovic kicks off a new MAD Skills series, this time looking at some
building blocks of Compose UI: layouts (such as Row()
and Column()
)
and modifiers. Simona and Jolanda Verhoef cover this material in
this teaser video and
this introductory video.
Leveraging the Snapshot Mutation Policies of Jetpack Compose
Shreyas Patil explores the little-seen second parameter to mutableStateOf()
:
the SnapshotMutationPolicy
. That interface tells Compose whether two
states are equivalent()
and, if they are not, can help merge()
the two.
Medium: Improving the Compose DropdownMenu
Peter Törnhult was unhappy with the performance of DropdownMenu()
, courtesy
of its use of Column()
, and wanted a bunch of other capabilities. The result
is a LargeDropdownMenu()
composable that handles larger lists better!
Medium: CollapsingToolbar with Jetpack Compose
Minami Munakata wanted a collapsing app bar, but only Compose Material3 offers one — this post walks through a complete alternative implementation, including a custom scaffold!
Composing the desktop
When Thomas Künneth is not trying to convince us to develop apps for foldables, he tries to convince us to develop apps for the desktop. Here, Thomas gives us an overview of Compose for Desktop, showing how the same composable can be used in Android and desktop UIs.
Medium: Large Screens & Foldables
Vinod Baste takes up the foldable cause, examining Compose Material3’s support for adaptive layouts, window size classes, and posture tracking.
Medium: Migrating Forms to Android Jetpack Compose
Moshe Waisberg looks at what it takes to migrate a typical sort of entry form
from the classic View
system to Compose Material. In particular, Moshe describes
a technique to help ensure your implementations match: layer the composable
over the original form on the Z axis temporarily, too see what is no longer in the
proper position.
Medium: Jetpack Compose - Ticket Shape
Max Tayler needed to render an image cropped to a ticket shape, with rounded
corners and semi-circular cutouts on two sides. Max assembled a Path
implementation to handle the cutouts, then wrapped that and the rounded corners
in a custom Shape
implementation.
Other Interesting Links
- Medium: An animated Start-Stop Button in Compose — part 2: Rounded Corners
- Medium: Implementing Photo Picker on Android + Kotlin + Jetpack Compose
- Jetpack Compose Tutorial: Replicating Dribbble Audio App Part 2
- Getting Started With Testing With Compose
- Building a Language Learning App with Compose – Part 2
- Medium: Tooltips in Jetpack Compose
- Medium: UI Testing | Jetpack Compose Navigation
- Medium: Validating forms in an android project both xml and compose
- Medium: Storage Access Framework (SAF) in Jetpack Compose
- Apple Swift ui vs Android Jetpack compose
- Medium: Jetpack Compose — quick review
- Jetpack Compose 101; Setup the Environment
Resource Roundup
100% pure code!
GitHub: slackhq / compose-lints
Slack is starting to publish a series of Lint checks to ensure that composables meet particular coding standards. Right now, these are just source code; a published artifact may follow. No word if your IDE issues a “knock-knock” sound effect when you fail one of these Lint checks. 😁
GitHub: dawidraszka / compose-permission-handler
Dawid Raszka has published a library to make it easy to request runtime permissions, including handling the three (yes, three) possible outcomes from a runtime permission request.
GitHub: fogsong233 / Dropper
GitHub user fogsong233 is working on utility code to make it easier to implement drag-and-drop between composables.
Other Interesting Links
- GitHub: takagimeow / adaptive-layout (simplified support for phones/foldables/tablets)
- GitHub: MateriiApps / panels (side panels)
- Gist: vighnesh153 / ExoVideoPlayerInJetpackCompose.kt (ExoPlayer with Compose controls overlay)
- GitHub: aiyu-ayaan / tts-engine (text-to-speech engine with Compose support)
…And One More Thing
Databinding is officially in maintenance mode.
(😐 ← this is my shocked face)
I have been warning folks about this on Stack Overflow for a couple of years. When
Compose UI came out with fanfare, “the writing was on the wall” for databinding.
I am grateful for the official statement, though, as that will make it easier to
steer people towards other options, whether that be view binding with the classic
View
system or Compose UI.
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?!?