Newsletter Issue #147

Published: 2023-01-03

Once again, I’m back! 👋

This week, we look at Compose for Desktop and Compose for NativeScript. We explore navigation as state and testing state restoration. We apply marquee effects to composables and crop some images. And we spend some time with decorationBox, despite it having nothing to do with holiday presents.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Why Does My UI Still Block Even With LaunchedEffect()?

LaunchedEffect() lets you start a coroutine when the composition is entered. However, you are still subject to the rules of coroutines — if you launch a coroutine on Dispatchers.Main, that will block the UI. And so you can get bitten by the default dispatcher for viewModelScope, even with LaunchedEffect(), as we see in this week’s highlighted Stack Overflow question.

With a SpannableString, there are ways to add accessibility “links” that can be read by TalkBack. See how to implement the same thing with an AnnotatedString in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Jetpack Compose Desktop in Production: my experience and gotchas

Alex Styl returns, taking a look at Compose for Desktop. Alex has been using Compose for Desktop for Ubidrop, and while it had some strong points, Alex encountered challenges with more advanced scenarios.

Introduction to Jetpack Compose for NativeScript

NativeScript is an open source cross-platform JavaScript-centric app framework. Eduardo Speroni describes a Compose plugin for NativeScript, allowing you to use composables alongside traditional NativeScript views in an app.

Medium: Decorating Text Field In Jetpack Compose

Often, we need a text entry field to have stuff around it: icons, borders, captions, and the like. Raheem Hameed discusses the decorationBox parameter to BasicTextField(), a slot API where you provide the wrapper contents around the field itself, so you can tailor that wrapper to match your design system’s needs.

Medium: Jetpack Compose OTP input field

Ban Markovic is back, this time looking at the ever-popular OTP or PIN input, where you want to collect text from the user but render each character in its own UI element. As it turns out, Ban’s solution also involves decorationBox, in this case largely ignoring the actual field and rendering the entered text in a series of boxes.

TJ Dahunsi explores the concept of treating navigation as part of app state, with an eye towards supporting different UIs for different screen sizes. In this approach, navigation is just another type of app data, managed by an observable repository. TJ also explores how one can leverage moveableContentOf() to have shared element transitions as you move from state to state, including moving from screen size to screen size (e.g., a resizable Chrome OS window).

Medium: Jetpack Compose New Photo Picker

Android 13 adds new photo picker APIs that avoid the need for permissions. Those were then backported by Google to earlier versions of Android, and Google also supplied PickVisualMedia and PickMultipleVisualMedia contracts for use with the activity result API. Daniel Atitienei explores using those contracts in a Compose UI app.

Medium: Testing State restoration - Compose

rememberSaveable() is a form of remember() that puts its saved vales into the saved instance state Bundle, so the data can be retained across configuration changes and some process restarts. In this post, Nav Singh explores using StateRestorationTester for testing composables that leverage rememberSaveable().

Medium: Jetpack Compose Migration: Best Practices and Strategies

Abhishek Saxena migrated a German<->English dictionary app from classic views to Compose UI and wrote about the experience. Abhishek also walks us through some of the other code cleanup and architecture changes that were made in support of the migration.

Resource Roundup

100% pure code!

GitHub: T8RIN / Marquee

Forget marquee effects solely for text! Malik Mukhametzyanov created a Marquee() wrapper composable that applies marquee effects for any composable, Text() or otherwise!

GitHub: rroohit / ImageCropView

Rohit Chavan brings us an image cropper composable. You configure the guidelines and corner circles, and it helps the user crop a photo or other image.

GitHub: t3chkid / branded-buttons-compose

GitHub user t3chkid put together a set of button composables that handle the branding rules around different social logins (e.g., “Sign in with Github”).