jetc.dev Newsletter Issue #84
This week, we look at composable sizes and what to do if things do not quite fit. We look at keyboard handling, theme swapping, and simulating classic LED matrix displays. We offer users scrollable pickers of numbers, times, or, well, anything. And I wonder how we are going to cope with the “just copy it” recommendation for dealing with Compose Material inflexibility.
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
Gracefully dealing with different font scales is a challenge in Android app development, inside or outside of Compose. Occasionally, you may want to more substantively change your UI for scaled-up fonts… but that implies that you know how much space the text takes up. See how to accomplish that in this week’s highlighted StackOverflow question.
You might want to create a composable that has a default size, yet allows that size
to be overridden by modifiers. That gets complicated, given the way that conflicting modifiers
“negotiate” a size, as we see in this week’s highlighted Kotlinlang
#compose Slack thread.
Posts, videos, and other new information related to Jetpack Compose!
Siva Ganesh Kantamani continues to poke at the Compose UI API, this time examining
KeyboardActions that we can pass into
TextField() and related composables.
Siva also explores using the
KeyboardController composition locals,
for things like manually changing the focus or dismissing the soft keyboard.
Matt Robertson looks at a standard recipe for having your composables react to the system dark mode setting… and then looks at what powers that recipe. In particular, Matt looks at how you can have more complex business rules for your composable theme, based on the system dark mode setting, manual user options, and anything else that you need.
Peng Jiang likes bottom navigation… so much so that Peng wrote a post about how to style
bottom navigation using both
BottomNavigationView from the Material Components for Android and Compose UI.
Peng briefly covers how to control colors, badges, and the like for each of these bottom nav implementations.
Alex Zhukovich encourages you to create custom components first, and build screens out of those
components. This runs a bit counter to how we tend to build UIs in the classic
simply because creating custom views is a significant headache. Compose UI dramatically simplifies
this, and Alex argues that building a robust component library is key for any significant Compose UI app.
Vishnu Haridas wanted an old-school 5x7 LED matrix display for displaying digits in a Compose UI app.
Vishnu’s post shows one approach, using a 5x7 set of
Box() composables, along with
animated effects for switching between digits, custom shapes and colors for the individual
dots in the display, and more!
Other Interesting Links
- How I Learned to Stop Worrying About Custom Components and Love Compose
- Skia shaders in Compose Desktop
- Medium: Jetpack Compose: Adding a Hilt ViewModel to the Navigation graph
- Google SignIn Compose
- List animations in Compose: Swipe to delete
- Medium: Jetpack Compose Hands On
- Medium: Guide on Jetpack Compose
- Medium: Jetpack Compose Side Effects — SideEffect
- Medium: Jetpack Compose. Base Layouts
- Medium: 4 Cool Facts About Jetpack Compose
100% pure code!
A couple of months ago, I pointed out the work that GitHub user theapache64 did in creating a project generator for Compose for Desktop theapache64 has created an expanded version of that generator, supporting multiple project templates, including a standard Compose UI project, Compose for Web, and more!
Every now and then, we need a reminder that while Compose UI is important, Compose overall is useful for other sorts of trees. In this project, Takahiro Menju demonstrates setting up a tree of nodes, then printing those in an ASCII tree that you might find in command-line output (e.g., a Gradle dependency report).
Other Interesting Links
- GitHub: X1nto / OverlappingPanelsCompose
- GitHub: Tgo1014 / DraggableScaffold
- GitHub: ValeryPonomarenko / compose-shimmer
…And One More Thing
A couple of weeks ago, on Kotlinlang Slack, Zoltan Demant wanted to know:
Is there a sensible way to support a smaller
TextField(width) than the material design one?
It turns out that
OutlinedTextField have a minimum width of
and its documentation (“you can override it by applying
Modifier.widthIn directly on a text field”)
apparently is incorrect.
Google’s Adam Powell pointed in Google’s standard direction for this, telling Zoltan to copy the code:
I think what you’d ideally want here is a way to implement your own text entry from the soft keyboard relationship on up. Drawing the text at all is something you want to have full control over.
BasicTextField is the place to start with the current API but I think we have some work to do in compose-ui itself to expose some lower level building blocks
As a result, Zoltan surrendered:
Alright 🙂 Ill leave it alone for now, the material library has covered all my needs thus far and I think that if I dabble with BasicTextField in an attempt to mimic 99% of the TextField functionality/look, itll just crush my hopes \& dreams in the long run with maintenance work. I appreciate the responses, thank you!
After all, even if we assume that all that is needed is to fork
that is at least 800 lines of code. Copying that code and making the adjustment
would not be that hard the first time, to result in some
But now Zoltan would be responsible for also re-copying
that code on every Compose Material release and re-making that adjustment. Otherwise,
at best, the customized
TextFieldWithSmallerMinWidth() would steadily depart
from the then-current
TextField() implementation. At worst,
would start to fail, if it depends on stuff that Google changes.
Compose Material is an opinionated library. I get that. However, IMHO, ideally Google would have gone with “opinions as overridable defaults” more than “my way or the highway”. This is particularly true for constants like minimum width and height, where the cost for allowing an override is just a slot in the API.
Of course, not all customizations will be simple constants. For example, Zoltan later asked:
Is it possible to make the label of a TextField float to the top even though the input is empty?
Once again, the behavior of hint-versus-floating-label is opinionated within Material Design.
In truth, API design is hard regardless of whether you have a function-based or a class-based API. A constant like a minimum width might not be in a place in a class where it could be overridden, for example. It is just that we have a lot of experience with class-based APIs and where/how to provide flexibility. We will need to learn the equivalent techniques for a function-based API.
Also, we may need to start figuring out three-way merges or some means of being able to copy composables, make minor tweaks, and still adopt changes made to the original composables.
- 2023-01-24: Locales! Relay! Effects! Paging! Foldables! Permissions! Date pickers! Bi-directional scrolling! And what your MaterialTheme means... for your SwiftUI code?!?
- 2023-01-17: New Compose patches and alphas! Dealing with Navigation for Compose! Scaffolds! QR codes! Server-defined UI! And @email@example.com has joined the BOM squad! 😁 💥
- 2023-01-10: onNewIntent() and composables! ContactsContract and composables! Balloons! QR codes! Pencils! And a focus on focus!