Last week was Labweek at Comcast, one of the best traditions at Comcast, where developers and designers can take some time to pursue ideas, learn new technologies or just work with folks you don’t usually get to work with. Though every week can be labweek in my world working at Comcast Labs, I still enjoy working on something completely different from the projects-on-record for a week. You can read about a few of my previous labweek prototypes here.
For this labweek, I took the opportunity to build something with Jetpack Compose, Google’s new UI toolkit for building Android apps. In the last couple of years I have worked quite a bit with ReactJS, SwiftUI and a LOT with Flutter (read my thoughts on Flutter here) , and it was interesting to see how all of them were starting to adopt the same patterns. From the sessions at IO and conversations at the Philadelphia Google Developers’ Group that I help run, I knew Jetpack was also headed the same direction, but it took me building an app to realize how close that was.
Compose vs. SwiftUI
Compose feels the closest to SwiftUI, borrowing not only the ideas of light weight layout containers (Rows, Columns, etc) but also the use of Modifiers to manipulate the View …sorry…the Composable. Even the structure of a typical compose file with a function that defines your composable and another, annotated with a preview annotation, that lets you preview your layout is identical to the SwiftUI edit/preview experience. The similarity even extends to the documentation experience: check out the SwiftUI tutorial and the Compose tutorial page layouts with text on left that scrolls with the code on the right. Heck, even my bugs are similar in both frameworks 😉
Compose vs. Flutter
While Flutter is similar to Compose, I do prefer Compose’s modifier approach to Flutter’s approach of composing behavior using a hierarchy of widgets, though the hot reload on a device/simulator that Flutter does is preferred to the preview experience on Compose, specially since previews cannot fetch live data from the cloud and my design was very remote image heavy.
I also find creating animations in Flutter a bit cumbersome, having to create AnimationControllers, TickerProviderMixins, Curves and callbacks. Jetpack Compose does seem to have enough complexity in their own system as well but I got a lot of mileage out of just using AnimatedVisibility with enter and exit animations, though SwiftUI with the `withAnimation` blocks is the clear winner here.
Random Lessons Learned
There were a couple of gotchas as I was building the app: For some functionality that I would consider core, like fetching remote images or making your app aware of things like WindowInsets, is only available as part of an external (Google authored) library called Accompanist. I had a bit of a hiccup because my version of that library wasn’t compatible with the version of Jetpack in my Android IDE. I do hope these capabilities get added to Jetpack Compose core instead of an external dependency that I’d have to track (I do prefer the batteries included approach). Also if you do plan to use the official samples as a starting point, note that some (or at least the one we were using) has a compiler instruction to fail on all warnings (that took like 2 hours to figure out)
A week of intense coding in compose gave me a lot of appreciation for this new direction for Android development. I was pleasantly surprised how productive I felt working on a completely custom Android UI. There is still a lot of features of Compose I haven’t tried out yet but am definitely looking forward to learning more. At this moment Compose is not officially out yet (the latest version is release candidate 1 that came out a few days ago), but I am sure Compose will enable some truly amazing UI experiences on Android in the next few months!
One thought on “Jetpack Compose: Rocketing in the right direction”
This might be of interest too, how Jetpack Compose can interop with legacy views. In my following sample project, all views AR composables overlaying an legacy OpenStreetMap MapView using library osmdroid.