jetc.dev Newsletter Issue #58
Published: 2021-03-30
beta03
is out, and it is as boring as was beta02
!
So, instead, we focus on modifier ordering, along with evergreen topics like themes and navigation. We also peek at using Compose UI on foldable/dual-screen devices, give our composables major motion, and see what Google’s Chris Banes has been up to recently. Plus, I encourage you to “eat your vegetables” and get your app architecture in a good place before diving seriously into Compose.
Beta Breakdown
Reviewing the release notes for the latest Jetpack Compose update!
As with past beta releases, there are relatively few changes to the API exposed
by beta03
. You might want to review the release notes if you are using:
-
DefaultMonotonicFrameClock
incompose-runtime
-
GestureScope
incompose-ui
-
FlingBehavior
incompose-foundation
-
BottomDrawer
incompose-material
Otherwise, you should encounter few modifications, if any.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
Left, Right, Left
Compose UI offers automatic layout orientation based on LTR/RTL languages.
However, what if you want to override that for a particular composable?
Learn how to use CompositionLocalProvider
and LocalLayoutDirection
for that in this week’s highlighted Stack Overflow question!
When Do We Clip?
The order of modifiers matters. Each modifier basically creates a composable that
wraps the preceding composable, and so a chain of modifiers creates a chain of
wrapped composables. Sometimes the order will appear to have no impact, and sometimes
the order will result in UI artifacts, as we see in
this week’s highlighted Kotlinlang #compose
Slack thread.
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Open Composables Via Notification with Jetpack Navigation
Igor Escodro is back, this time looking at how to integrate Compose UI with
a common system feature: the Notification
. Igor shows how to use Navigation
for Compose and deep links to get a Notification
to not only launch your
activity but to show a specific composable from your nav graph.
How to Style and Theme an App With Jetpack Compose
Ryan Kay takes us on a tour of how we handled styles and themes in the classic View
system and how those approaches map to the techniques used with Compose UI.
Android Jetpack Compose: Theme Made Easy
Elye continues a long series of “Made Easy” posts, with his own take on setting
up your colors, typography, and more using MaterialTheme()
as a foundation.
Video: Migrating to Compose
Prateek Prasad delivered a lengthy presentation to GDG BlrDroid on how to adopt Compose UI and migrate an existing fragment-centric app to this new system.
Navigation with Animated Transitions Using Jetpack Compose
Johann Blake wrote about the limitations with Navigation for Compose and explores a custom-built navigation framework, with a particular emphasis on animating the transitions between screens.
Video: Getting Started with Jetpack Compose
Maia Grotepass delivered a presentation to GDG Johannesburg, with an introduction to Compose and Compose UI, including a walkthrough of many of the steps in the Jetpack Compose basics codelab.
Video: Jetpack Compose Bottom Navigation
YouTube user Code Zombie continues a tour of Compose UI, this time reviewing setting
up bottom navigation using a Scaffold()
, Navigation for Compose, and BottomNavigation()
.
Re-gaining Orientation #3
Thomas Künneth continues an exploration of portrait and landscape modes and how they work with Compose UI. In this case, though, Thomas focuses on a different scenario: foldables. In particular, Thomas explores how to adapt a landscape-style UI to cases where the hardware, more so than your app, dictates where the UI split should occur, courtesy of a fold or hinge.
Jetpack Compose Foldable and Dual-Screen Development
Microsoft and Joy Liu agree with Thomas Künneth, that foldables are important. I am sure that the fact that Microsoft sells a dual-screen Android device is purely a coincidence. 😁 In this post, Joy expands upon an earlier post to look at various UI design patterns for foldable/dual-screen devices and how to implement them using Compose UI.
Other Interesting Links
- Prime Table Generator in Jetpack Compose
- Building UI with Jetpack Compose. Part 1: Bottom Sheet Implementation
- How much can we share in Kotlin MultiPlatform
- Jetpack Compose Ep:11 — Switch App
- Writing List Views for lazy android developers
Resource Roundup
100% pure code!
GitHub: google / accompanist
Chris Banes’ accompanist
series of libraries is now An Official Google Thing™ 🎉
In addition to the image loaders, theme adapters, and system UI libraries from
before, it now adds a composable pager (akin to ViewPager
) and a flexbox-style
container.
GitHub: fornewid / material-motion-compose
The Material Design spec has a specific motion system.
GitHub user fornewid has created a library of composables that implements several
of those motion system specifications (e.g., FadeThrough()
), plus a MaterialMotion()
composable to allow you to easily apply different motions based on app state.
GitHub: Tlaster / PreCompose
GitHub user Tlaster is back with another library, this one offering Kotlin/Common
code for navigation, viewmodels, and a LiveData
equivalent. The objective is to
allow you to write more of your app logic in commonMain
of your Kotlin/Multiplatform
project, by replacing Jetpack dependencies with intrinsic Android ties.
GitHub: Elbehiry / PCard
Mohamed Elbehiry brings us a beautiful payment card screen written in Compose UI, complete with animations as the user fills in the card data, all in around 500 lines of code!
Other Interesting Links
- Gist: warting / ZoomableImage.kt
- GitHub: manueldidonna / undo-redo-animation
- GitHub: theapache64 / klokk
- GitHub: tylerbwong / stack
- GitHub: Madonahs / The-Sports-DB
…And One More Thing
Jetpack Compose is crazysexycool.
(presumably, you agree — otherwise… this might be the wrong newsletter for you)
However, be careful not to sacrifice other essential concerns of your app development while chasing the cool.
In particular, before you embark on a serious migration of an app to Compose UI, consider first whether your app architecture is in a good place. Trying to change your architecture along with the UI rendering is likely to be a massive undertaking. Of the two, dealing with the architecture now, while Compose is still in beta, likely is a better option than is worrying about Compose now and “kicking the can down the road” on architecture concerns.
Besides, a lot of what we are aiming for in architecture will simplify any Compose migration. A key objective of modern Android app architecture is to get all non-essential code out of your activities and fragments and into other things: viewmodels, use cases, repositories, data sources, etc. Partly, all of this is good for long-term maintainability and testing. But it also limits the excess “mental noise” that you will have to deal with as you migrate your UI from views to composables.
So, take a tour of your app code, and if you have things unrelated to UI presentation or system navigation… see if you can move it somewhere else:
-
Disk I/O
-
Network I/O (TCP/IP,
DownloadManager
, etc.) -
Peripheral I/O (Bluetooth, BLE, NFC, printing, USB, etc.)
-
Sensor readings (GPS, accelerometer, etc.)
-
Non-presentation aspects of camera integration
-
Setting up
WorkManager
work,JobScheduler
jobs, etc. -
And so on
The more of that you can get out of your activities and fragments, the more likely it is that you will be able to swap in composables cleanly as replacements for your layouts and views.
Or, you can subscribe to the Atom feed or follow Mark Murphy in the Fediverse.
Recent Issues:
- 2024-12-10: A Compose Multiplatform alpha! Hot reload! Presentation! Sprites! Calendars!
- 2024-12-03: Rebecca Franks on clipping and masking! Stefano Natali on graphicsLayer()! FunkyMuse on type-safe nav results! And... if we have enough maps, do we need to store our maps in a Map?!?
- 2024-11-26: Math! Shared element transitions! Custom modifiers! Macrobenchmark! Adapting to platform-specific design systems! And... why does wrapContentSize() not wrap my content size?!?