jetc.dev Newsletter Issue #78
In this week’s issue, we look at limitations on how we can construct design
systems in Compose UI. We also look at the history of the
how Square adapted Workflow to Compose, and how we might add a drop shadow
Text(). I point out some issues with
debug builds and Compose performance.
Plus, we see how a Google engineer uses Compose Material to build a shrine.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
Sometimes, we need a dashed or dotted line in a UI. There are multiple possible
solutions to this problem, and this week’s highlighted Stack Overflow question
explores two: drawing a dashed line on a
Canvas() and creating a custom
to apply to the background of something like a
We are encouraged to create custom design systems as part of our work with Compose UI,
wrapping existing composables in ones that implement our design requirements. However,
you still wind up needing to offer flexibility with those composables, owing to how
Compose is set up, as we see in this week’s highlighted Kotlinlang
Posts, videos, and other new information related to Jetpack Compose!
Louis Pullen-Freilich, Matvei Malkov, and Preethi Srinivas of Google’s Compose UI
team give us a tour of the history of the
Button() composable. Its API changed
a fair bit in its two-year history, and the team explains why they made those API
changes, ranging from developer feedback to improving discoverability to dealing with
underlying Compose changes.
Chris Sinco on Google’s Android tools team walks us through the use of Compose UI, building an implementation of the Shrine Material Design “study” and showing how Material Design gets expressed through composables.
Square created a library called Workflow that represents their foundation for constructing UIs in Android and iOS. Zach Klippenstein recounts Square’s approaches towards adopting Compose support in Workflow, as an in-depth analysis of how to take an opinionated architecture framework and adapt it to a similarly-opinionated UI framework.
Sam Edwards is back, looking at how to add a drop shadow effect to
This is a stock option for
<TextView> and is somewhat less straightforward
to do in Compose UI. Sam illustrates a few approaches, one of which hopefully fits
Rivu Chakraborty delivered a droidcon Online presentation, looking at the work involved in migrating an existing app to Compose UI. This includes what changes you should make to your code before starting that migration, to make it easier to adopt Compose incrementally.
Google Podcasts allows you to adjust the playback speed of the podcast that you
are listening to, using a widget reminiscent of a
SeekBar, but with custom
styling and behavior. In this post, Francesc Vilarino Guell shows how to create
a composable with the same basic look and feel, including handling the gestures,
managing the animations, and snapping to specific values.
Google’s Accompanist family of libraries contain a wide range of composables and related code. Oleg Zhilo gives us a quick tour of what is all in those libraries and what their roles are.
Udit Verma has started a series of post looking at the
...Effect series of composables.
The overall vision is that composables should be free from side effects, which means
if you do need side-effects, you need to handle them with care.
lets you run coroutines with a scope tied to the current composable, and Udit shows
how you can use it.
Other Interesting Links
- How to make Jetpack Compose navigation easier and testable
- Medium: List view with Pagination using Jetpack Compose
- How to animate BottomSheet content using Jetpack Compose
- Detect Instagram-like gestures with Jetpack Compose
- Video: Gradient Button
- Medium: Progress Button using JetPack Compose : SSJetPackComposeProgressButton
- Medium: Handling State in Jetpack Compose
- Adopting Jetpack Compose: Theming
- Medium: Jetpack Compose — Building a RecyclerView with StickyHeader
100% pure code!
Other Interesting Links
- GitHub: david-varela / bottomNavScaffold
- GitHub: humawork / compose-charts
- GitHub: farhanroy / ComposeCountryCodePicker
…And One More Thing
Compose is set of libraries. On the whole, this is a good thing, as this newsletter has covered in the past. Basically, we as developers get to control when we move to new versions of the library, and device manufacturers have less impact on the UI of our apps.
However, having the entire UI framework come from libraries has a cost: initial app performance.
Java/Kotlin source code get compiled to Dalvik bytecodes, which go in the DEX files of our apps. Eventually, the OS does work based on those bytecodes, in one of three ways:
Just-in-time (JIT) compiled, where the bytecodes are converted into CPU-specific instructions and cached in RAM for later reuse by this one process
Ahead-of-time (AOT) compiled, where the bytecodes are converted into CPU-specific instructions and are saved on disk for later reuse by future processes
In effect, framework classes, like
ImageView, are AOT-compiled.
Eventually, the DEX files in your apps will also have key portions be AOT-compiled.
However, that does not happen immediately — Android needs your app to run for
a while before it knows what is worth saving. In the beginning, your DEX files will
be interpreted or JIT-compiled, and that will slow down execution.
As a result, a Compose UI app may run slower than will an equivalent app using
View system, at least until the AOT compilation process catches up.
Also, Compose relies a lot on R8 optimizations, and normally those are not run
debug builds, as R8 slows the build process. So, developers and others who
rapidly churn through debug app builds will have even worse performance:
AOT compilation results get thrown out when the app gets replaced by a new build
If you are using
debugbuilds, R8 optimizations are not performed
Developers may need to educate the QA team, product managers, and others about
this and suggest that performance should be gauged based on
release builds that
have been installed for a while.
For more, see this Kotlinlang
#compose Slack thread
that depicts the difference between different app compilation states and their
- 2021-09-07: 1.1.0-alpha03! Parcelable in Navigation... or not! SideEffect! Recomposition! Sharing KMP code! Grids! Timeline UIs, and timelines of stable releases!
- 2021-08-31: rememberUpdateState()! Paging! AndroidView()! @TouchlabHQ on animations and a composable KaMP Kit! Decompiled composables! And how sloppy use of custom views can hinder migration to Compose UI!
- 2021-08-24: 1.1.0-alpha02! Dependent modifiers! Input validation! Live text! Auto-sized text! And... performance anxiety?!?