Newsletter Issue #208

Published: 2024-04-02

This week, we spend a lot of time on internationalization, localization, and string resources in Compose UI. We also explore maps, animate items in lazy lists, and see a clipped circle shape for use in avatar lists and the like.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can We Swipe to Change Activities?

Inertia is very real when it comes to programming techniques. Nowhere is that more prominent in modern Android development than with the notion of activities-as-screens. Once developers break free from that mental constraint, things become much easier, as we see in this week’s highlighted Stack Overflow question.

Can We Get the Scroll Amount of a TextField()?

Short answer: no. While the new BasicTextField() (formerly BasicTextField2()) offers an API for this, it is not ready for the desired use case: a rich text editor. Learn more in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Medium: Introducing Trio | Part I

Airbnb released Mavericks as an open source library back in 2018, as an MVI-style system for dealing with state in viewmodels. While that was originally used with fragments, Eli Hart explains how Airbnb migrated their app to use Mavericks with Compose UI.

Medium: Styling Internationalized Text in Jetpack Compose

Many apps need some text that has styles applied to parts of it, such as for clickable links. Handling that for localized text can be a challenge, as the positions of the styled portions may change based on sentence structure. Burak Karaduman shows us a ClickableLocalizedText() that helps to manage that complexity.

Medium: String resources API for Compose Multiplatform

Dealing with localized strings in the classic View system involved string resources… but that only worked on Android. Compose Multiplatform now offers its own take on string resourceds, and Gérard Paligot explains how they resemble Android string resources and how to use them, including the current limitations that they impose.

Medium: Per-App Language Preferences in Jetpack Compose

A bunch of apps implemented their own per-app locale system, so users could have their app render in a language different than the one associated with the system locale. Android 13 standardized this, and the Jetpack AppCompat library offers a backport. Lucian Ghimpu explains how to use this in a Compose UI app, letting the user choose a language and then using string resources associated with that language.

Medium: How to Use Google Maps in Jetpack Compose: Step-by-Step Android Guide

Google Maps is extremely popular. Rıdvan Özcan shows us how to use Maps for Compose, from the basics of the GoogleMap() composable to adding markers, polylines, and map controls.

Medium: A preview of Animating LazyList items in Jetpack Compose

LazyColumn() and LazyRow() are great, but they lacked the item animation flexibility of RecyclerView. The animateItemPlacement() modifier only handled reordering of the list, not additions or removals. Gergely Kőrössy walks us through the new addition/removal animation support in Compose Foundation 1.7.0 alphas, including the current limitations.

Resource Roundup

100% pure code!

GitHub: JustinGeorgeJoseph / ClippedCircleShape

A common UI pattern is a row of overlapping circle-cropped images, such as a row of user avatars. Justin George implemented a ClippedCircleShape designed for use with the clip() modifier and this UI pattern. It supports clipping in either of the four cardinal directions, for rows or columns of circles.

GitHub: wasabeef / compose-gap

One annoyance with using Spacer() in a Row() or Column() is that you have to use width (for Row()) or height (for Column()) to set the size. Daichi Furiya created a simple Gap() composable that “knows” if it is in a Row() or Column() and sets the width or height accordingly.

Notable Releases

The Compose Multiplatform Wizard has been updated with experimental WasmJS support, support for multiplatform resources, up-to-date dependencies, and more.