jetc.dev Newsletter Issue #101

Published: 2022-01-25

While we patiently await a 1.1.0 stable release, we look at switching locales and switching Switch(). We look at Microsoft’s latest foldable support library, testing with Robolectric, and criteria for navigation solutions. We examine a segmented progress bar and an OTP input composable. Plus, Reddit ponders Compose for iOS, while I ponder Compose… for PDFs.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

How Can We Recompose Due to a Locale Change?

Android 13 is rumored to have a “panlingual” feature, where users can indicate a particular locale to use on a per-app basis. For older devices, we are stuck with hacks, using setLocale() on a Configuration. But, how do we get our composables to recompose when we change the locale, particularly if the change switches from LTR to RTL languages? The answer, like many edge cases in Compose, is a bit tricky, as we see in this week’s highlighted Stack Overflow question.

How Do We Deal with Switch() State?

Compose UI elements are stateless… except when they are not. That can lead to UI inconsistencies, and the occasional Compose UI bug, as we see in this week’s highlighted Kotlinlang #compose Slack thread.

Composable Commentary

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

Compose… for iOS?!?

A Redditor pointed out that JetBrains has some commits up showing a version of Compose/Multiplatform that targets iOS. Preliminary indications are that it uses the Skia port to iOS, akin to how Flutter supports iOS.

Jetpack Compose WindowState preview

The Microsoft team supporting the Surface Duo has a preview release up of a WindowState object that wraps up a bunch of information for dealing with foldables, such as the direction of the fold, the current fold state, and more!

Video: Exploring advanced Jetpack compose features

Filip Babić is back, with a presentation from Kotlin KODERS 2021. Here, Filip looks at state management (including integration with various reactive frameworks), animations, and creating reusable composables.

Medium: Blazing fast Compose tests with Robolectric

Sebastian Lobato Genco created the Resaca library that I mentioned last week. In this post, Sebastian explains how to set up non-visual Compose tests using Robolectric, for testing infrastructure composables like the ones in Resaca.

Medium: Grouping Semantics in Jetpack Compose UI

Ataul Munim walks us through customizing the semantic nodes for our composables, as those nodes drive accessibility features like TalkBack. In particular, Ataul explores replacing a bunch of individual semantic nodes with ones representing logical groups of composables, to simplify navigation for those using accessibility services.

A Tale of Two Composable Default Text Sizes

Rebecca Stockbridge warns us that Text() (a common composable) and ClickableText() (a far less common composable) have different default font characteristics, particularly font size. Rebecca wandered through their respective implementations to track down where the font sizes get defined and why they differ.

Tweet: LocalView

Hugo Visser, in a tweet, reminds us that if we need a View on which to call some functions — such as setKeepScreenOn() — there is a LocalView composition local that we can use.

Here, I lay out a set of candidate criteria to use when evaluating the vast array of possible options for navigation frameworks in Compose UI apps. Note: I do not make an actual recommendation, because how I weight criteria could very easily differ from how you would weight them.

Medium: Jetpack navigation: Pitfalls and recommendations

Medium user Hamza points out various challenges when using Navigation for Compose and offers some solutions, such as using a sealed class to try to avoid typos when referencing routes.

Resource Roundup

100% pure code!

GitHub: StephenVinouze / SegmentedProgressBar

Stephen Vinouze created a progress bar that shows distinct segments in its progress, such as for indicating various steps along the way for some overall operation to complete. See this blog post for more!

GitHub: ibraheemalazzawi / android-compose-otp

Ibraheem Al-Azzawi brings us an OtpComponent() composable for collecting a six-digit OTP code, perhaps for use as part of a two-factor authentication system within your app.

GitHub: JyotimoyKashyap / CircularStats

GitHub user JyotimoyKashyap created a CircularStats() composable, suitable for showing progress or other values using a circular presentation.

…And One More Thing

Creating PDF files is a remarkably popular thing to do, even in 2022, and even on phones. A lot of questions pop up in Stack Overflow from Android developers trying to figure out how to create PDFs. Many try using Android’s printing framework, which is not designed to create PDF files as much as it is designed to create PDFs for printing. Some work with the iText PDF library, which is a fine library but whose license (GPL) causes problems for some projects. Few seem to be using Relatively few seem to use Apache PdfBox by way of Tom Roush’s Android port, though that may be a mix of project obscurity and limited documentation.

Given that we have composables for lots of UI targets, I wonder if and when somebody will try creating Compose for PDF.

Skia — the 2D graphics layer that powers Compose for Android, Compose for Desktop, some of Compose for Web, and maybe Compose for iOS — already has a PDF backend called SkPDF. In theory, Skiko — the Kotlin Skia wrapper — could write to SkPDF. With luck and work, the existing Compose UI layer could be used to create PDF content. What would remain would be surfacing PDF-specific constructs, such as “start a new page”.

Overall, creating PDFs might no so much exercise Compose as it would exercise the UI logic baked into Compose UI. Developers will be more familiar with that API than those of iText or PdfBox, so in theory it might be easier for them to create PDFs using composables they already know. There might be ways to better leverage Compose, such as using recomposition to advance to the next page in the document.

Even if using SkPDF proved to be impractical, creating a composable library atop of PdfBox might make PDF generation be more approachable to more Kotlin developers, particularly from within Android apps.

Is this practical? I don’t know. PDF generation is enough of a pain point, though, that it would be interesting if somebody gives this a try.