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.
Navigating in Compose: Criteria
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.
Other Interesting Links
- Medium: Requesting Multiple Permissions in Jetpack Compose
- Medium: Add a developers menu to your Compose app with Tweaks
- Medium: Jetpack Compose: Detect the number of fingers touching the screen
- Medium: Highlight filtered Text in Compose While Using Search
- Creating a Flipped Box Card in Android Jetpack Compose
- Creating a Custom Animated Shimmer Effect with Jetpack Compose
- Video: Intro to Animating things with Jetpack Compose
- Medium: Jetpack Compose Side Effects Made Easy
- Medium: Correlating Jetpack Compose Side Effects
- App widgets in Android with Glance
- Medium: Custom Jetpack Compose Chips
- Medium: Remember, Remember Jetpack Compose
- Medium: Jetpack Compose — Pulsating Circles Animation
- Medium: ViewPager in Jetpack Compose with dot indicators (within minutes)
- Jetpack Compose Is A Real Game Changer for Android Development
- Medium: Jetpack compose — A primer
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.
Other Interesting Links
- GitHub: hiteshchopra11 / JetCalendarView
- GitHub: timeline-notes / compose-code-editor
- GitHub: danchoo21 / compose-glide-image
- GitHub: umutsoysl / ComposeCreditCardView
…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.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-10-01: Lazy grids! Focus! @colinmarsch@androiddev.social on CMP accessibility! @skydoves@androiddev.social on Landscapist! @sinasamaki@androiddev.social on Slider()! And... what is it?!?
- 2024-09-24: A Compose security fix and a new alpha! clipToBounds()! Localization! offset()! @skydoves@androiddev.social on server-defined UI! Bottom sheets! And... someone set us up *3* BOMs?!?
- 2024-09-17: Compose 1.7.1 and Compose Multiplatform 1.7.0-beta02! Flow layouts! TV Compose! SharedBounds! Image cropping! And... why does remember() not seem always to remember?!?