jetc.dev Newsletter Issue #151

Published: 2023-01-31

alpha05 dropped, including a significant change for Wear Compose, pointing to future Material3 support on your wrist!

Beyond that, we look at LaunchedEffect(), see how our UI tests can be flaky, and figure out why our composables are so darn slow. Plus, we look at auto-sizing text and more options for navigation.

Ooooo… What Did We Get?

Reviewing the release notes for the latest Jetpack Compose update!

Version 1.4.0-alpha05 of Compose UI is out, including:

  • onHover support for ClickableText()

  • Test functions (e.g., runComposeUiTest()) that take a CoroutineContext parameter

  • DatePickerDialog() in Material3 (1.1.0-alpha05)

  • Various bug fixes

Wear Compose now has a 1.2.0-alpha03 version. Besides bug fixes, the big thing is that ScalingLazyColumn() has moved from androidx.wear.compose.material to androidx.wear.compose.foundation.lazy, both in terms of packages and in terms of artifacts. Not only is ScalingLazyColumn() not really tied to Material, but the Wear Compose team is starting work on Material3, so some things will move from androidx.wear.compose:compose-material to androidx.wear.compose:compose-foundation as part of that.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

When Does LaunchedEffect() Fire?

LaunchedEffect() is supposed to be executed once for a composition, even if that composition gets recomposed. If it seems like yours is being executed more often, perhaps the composition containing the LaunchedEffect() is getting disposed and recreated, rather than simply being recomposed. Learn more in this week’s highlighted Stack Overflow question.

No, Really, When Does LaunchedEffect() Fire?

Sometimes, you may be trying too hard to have too-simple of a LaunchedEffect(). For example, if you think that you want your LaunchedEffect() to not run on the initial composition (but only on recompositions), there may be a better solution, such as using drop() on a Flow. See an example in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Medium: Density, Devices and Flaky Tests

Google’s Alex Vanyo notes tests need to test what they are testing. That may sound circular. The problem stems from testing something similar to what they need to test, which may lead to failures. Alex specifically examines how density scaling may result in slightly different calculations depending on the scaling factor, and how that can make a composable test flaky.

Medium: Optimize or Die. Profiling and Optimization in Jetpack Compose

Sergey Panov explores how to determine where your composable time is being spent, from measuring over-composition to CPU and GPU profiling techniques.

Relay Anchor Leg: Overall impressions

Kristen Halper wraps up her three-post series on Relay, looking at some of her favorite features (e.g., synchronization of comments) and where she hopes Relay will go in the future (e.g., better accessibility support).

Ask other apps for photos, files and more using ActivityResultContracts

This week, Alex Styl looks at rememberLauncherForActivityResult(), the composable bridge to the ActivityResultContracts approach for interacting with other apps. Alex explores pretty much all the ActivityResultContracts options (e.g., CreateDocument(), PickContact(), StartActivityForResult()) and also outlines how to create your own custom contract.

Medium: Compose these composites

Last week I pointed out Composites Fiberglass. This week, Vladimir Raupov walks us through Fiberglass and how we can use it to assemble complex composable UIs from smaller building blocks.

Medium: Compose Multiplatform Web

Debdutta Panda walks us through setting up a Compose for Web project, what the template’s generated code does, and how to serve the resulting Web code for testing in a browser.

Medium: Animated Selector in Jetpack Compose

Peter Törnhult used AnimatedStateListDrawable with the classic View system for things like bottom nav tab icons, so the selected state looks different than the normal state. Peter wanted to reuse those drawables, so he used an AndroidView() to bridge the gap.

Resource Roundup

100% pure code!

ResponsiveText

Fabrice Thilaw created a ResponsiveText() composable that provides support for different text scales, configured via a textScale parameter. In other words, ResponsiveText() covers auto-sizing the way the autoSize attributes do in the TextView widget.

Guia

Roudi Korkis Kanaan offers another navigation library for Compose UI, with supports for screens, sheets, and dialogs. It also uses a NavigationKey class to wrap up destination identifiers and arguments to be passed to those destinations.

GitHub: uragiristereo / safer-navigation-compose

If you would prefer to stick with the official navigation option, Agung Watanabe created a wrapper around Navigation for Compose that offers type safety on arguments, leveraging kotlinx.serialization.