jetc.dev Newsletter Issue #105
Published: 2022-02-22
This week, we look at rotating composables, both permanently and as part of a swinging animation. We also see Google’s Chris Sinco build a shrine, implement the “action mode” UI pattern, and explore various animation API options. We look at composables that handle the animation for us, such as flipping cards or animated heart outlines. And I continue grumbling about Compose performance, this time pointing out a homebrew way of improving our results without a full minification pass.
Note: This newsletter will take a one-week break after this issue and will return on March 8th!
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
How Do I Rotate a Composable?
Compose Material offers a Slider()
composable, but it is horizontal. If you want
a vertical slider, you could rotate the Slider()
, though since it responds to user
input, that gets a bit tricky. Learn how to pull this off in this week’s highlighted
Stack Overflow question!
How Do We Use ComposeView in an AutoCompleteTextView?
A key part of migrating to Compose UI is ComposeView
, to be able to wrap a composable
in a View
. This works in most cases, but there are edgy edge cases where using
ComposeView
is challenging… such as in the drop-down portion of an AutoCompleteTextView
.
Learn some ways of trying to pull this off in this week’s highlighted Kotlinlang
#compose
Slack thread!
Composable Commentary
Posts, videos, and other new information related to Jetpack Compose!
Video: Building Shrine in Compose
In a series of three videos, starting with the one linked to above, Google’s Chris Sinco works through building the Shrine “Material Study” project using Compose Material. Part two and part three are also available.
Medium: How To Collect Flows Lifecycle-Aware In Jetpack Compose
Yanneck Reiß points out the lifecycle limitations of collectAsState()
for Flow
and examines using flowWithLifecycle()
to improve upon that. Yanneck then
wraps up the desired pattern in a rememberFlow()
extension function.
Medium: Building contextual mode of top app bar in Jetpack Compose
When the action bar pattern was introduced, “action modes” were included. These might
be activated on a long click of a list item, where the action bar theme and actions
would change to represent operations on the long-clicked-upon item. Tushar Kathuria
explores implementing the same UI pattern in Compose Material, showing how a simple
State
can be used to drive whether your TopAppBar()
is in regular or contextual mode.
Medium: Android’s IME Actions: Don’t ignore them.
That button in the lower right corner of your soft keyboard is the “action button”.
Not only can we choose which style to use for that button, but we can get control
when it is clicked, to navigate, switch focus, or otherwise help our user through our
UI. In this post, Kasem SM explores how we do this, leveraging keyboardOptions
and keyboardActions
on TextField()
.
Medium: The 3 Jetpack Compose Animation Transition Low-Level APIs
Elye continues exploring Compose UI’s animation APIs, this time comparing and contrasting
animate...AsState()
, Animatable
, and Transition
, for achieving various animation
effects in your app.
Medium: Conditional Navigation in Jetpack Compose
Francesc Vilarino Guell is back, this time looking at conditional navigation,
where your navigation destination varies by circumstance. The classic scenario
for this is when the user needs to log in before they can access the main portion of
your app, and so when the app starts you need to conditionally show the login screen
instead of the main screen. Francesc looks at using Navigation for Compose for this,
using LaunchedEffect()
.
Medium: The Art of Swing Effect With Jetpack Compose
Stephen Vinouze gets into the swing of things, examining how to use Compose animation
APIs to have a composable rotate around a particular point. This involves customizing
the transformOrigin
of the graphicsLayer()
modifier, so your animation effects
use a different origin than the center of the composable.
Other Interesting Links
- Writing UI Tests for Pager Layouts in Jetpack Compose
- SnapToFit Effect with JetpackCompose
- Animation in LazyColumn and LazyRow in Android Jetpack Compose
- Medium: MaterialYou — Dynamic Colors With JetPack Compose
- Video: Using Jetpack Compose with Square’s Molecule Library
- Medium: Learn Jetpack Compose Animated Content
- Medium: Clean architecture in Android (Jetpack Compose, Paging 3.0, Kotlin, MVVM) ーPart- 2
- Medium: Jetpack Compose: Concepts, principles and construction of an architecture in a multi module project. Part 1
- Medium: Text Recognition with Jetpack Compose and CameraX
- Medium: Text Translation with Jetpack Compose
- Slides: Jetpack Compose: The new Way of Building Android UI
- Medium: Anime App with Kotlin
Resource Roundup
100% pure code!
GitHub: wajahatkarim3 / Flippable
Wajahat Karim offers us a Flippable()
composable, for animating a flip transition
between the front and back of something, such as a card. Flippable()
provides slots
for the front and back composables, plus a FlipController
for triggering the flip.
GitHub: jkuatdsc / form-builder
GitHub user jkuatdsc published a library for helping you manage a form in Compose UI.
Here, a “form” is a collection of text fields, where the library offers a FormState()
container for individual field states, with centralized validation of the field contents.
Gist: c5inco / HeartRate.kt
Google’s Chris Sinco brings us a heart icon that animates colors along its path, inspired by this tweet.
…And One More Thing
I mentioned last week how Compose UI’s performance issues can collide with Wear OS’s performance issues, at least on poor-CPU watches. Obviously, there are poor-CPU phones as well, particularly older ones, and some developers run into problems more generally.
This leads to Slack threads like this one,
where Zoltan Demant got better performance by creating a staging
build type:
buildTypes {
debug {
minifyEnabled false
shrinkResources false
signingConfig signingConfigs.debug
}
release {
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
staging {
initWith release
minifyEnabled false
shrinkResources false
}
}
By and large, this staging
build type is equivalent to debug
, just with debuggable
set to false
. As Google’s Adam Powell noted:
ART changes its JIT behavior based on whether the app is debuggable
So, there is some “method to the madness”, and it is plausible that this indeed will help. I hope to try it out in the coming days.
One the one hand, it is great that we are finding these things. On the other hand, it is unfortunate that we in the community are having to come up with these semi-random approaches to address the problems on our own.
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?!?