Newbie question about colors in Compose/Material 3 world. I have an app in iOS, it has a number of n...
t
Newbie question about colors in Compose/Material 3 world. I have an app in iOS, it has a number of named color assets. I have used a script in the past that harvests those and creates a colors.xml file for the Android sibling. The names/keys of the color tend to be in the design language the designer has used for the thing (e.g. "text_prominent", "instruction_gray", etc). I've done a tutorial or two with the M3 color scheme stuff, but it remains a bit unclear how I reconcile these two worlds. I don't mind trying to use "primary" etc where it makes sense, but I need "keyed colors" in various custom places as well. What is the idiomatic way to do that going forward? I know that I can still just use the colors.xml file and then put things like
Copy code
colorResource(id = R.color.row_border))
all over, but that gets really verbose. I'd honestly just like to write extension methods on Color (e.g.
Color._row_border
), but I think that's considered Not Cool? And I'm not sure having things like
RowBorder
at the same level of
Purple80
is the way to go either.
s
So if I understand you correctly, you got a m3 colorScheme working, but you jusy got some extra colors which don’t fit this scheme and you still want to be able to access them using MaterialTheme.colorScheme.foo right? If yes, take a look at this https://developer.android.com/jetpack/compose/designsystems/custom#extending-material And here’s some thread where I had to do this exact thing to add
containedButtonContainer
and
onContainedButtonContainer
to MaterialTheme
t
Thanks! I did the tutorial a while back, but this doc is better. I'm impressed that doing extensions on Color is actually the first selection. I'm a little unclear on why I'd want to do the more elaborate solutions? I like the consistency with Color.White, Color.Blue, etc. I'm a little not sure though why they don't then have Color.Primary, etc. My guess is because primary resolution is more than just "is light or dark", so there needs to be an adjustable context to change it as it goes down the composition tree?
Uh ho. I misread. One little s. The example extends Colors, not Color.
Even more confusing, if I do "Colors" it does some CalendarContract thing. But I think for M3, I'm supposed to extend ColorScheme?
s
Yes it'd be colorScheme for m3. Having it as an extension on colorScheme gives you the implication that it both supports dark and light theme implicitly and it will recompose automatically if the color changes. That's what's on my mind at least. Not quite sure about the other things you mentioned about Color.White and so on, I don't think I followed you there.
t
Yeah, I was confused. You can access known colors (e.g. white, blue) directly from Color, which is terse and concise. When prototyping, I'll often just throw a Color.Red or Color.Green somewhere. Symbolic/keyed colors seem to route through the theme. When I first glanced at that documentation, my brain saw
Color
instead of
Colors
, and thought they were suggesting just extending Color with addtional dynamic constant names. And I was kind of appreciating that getting a color (dynamic or static) would just be a short Color.Something. But alas, the documention does not suggest that. To actually do that anyway, having done a little bit of experimentation, the correct incantation would be something like:
Copy code
val Color.Companion._TextDark:Color get() = Color(0xFF_22_22_22)
s
Yes, but in general it's very rare in my experience for a color not to need a dark/light alternative anyway, so doing this _TextDark color is quite dangerous if you use it from the wrong mode (light/dark)