https://kotlinlang.org logo
#compose
Title
# compose
m

Manuel Unterhofer

11/16/2023, 10:20 AM
Does anybody know why material 3 replaced `interface`s with `class`es for
ButtonColors
,
TextFieldColors
, etc.? It’ll limit user-space options now
😞 3
c

Casey Brooks

11/16/2023, 4:02 PM
I’m not entirely sure, but my guess would be to help enforce Stability of those classes for better performance. Also there’s probably not much of a good use case for letting them be interfaces when the typical way to change colors in Compose is through the Theme’s colors, or by passing parameters to the functions like
ButtonDefaults.buttonColors()
s

shikasd

11/16/2023, 5:57 PM
The previous model was quite flawed, as it forced
@Composable
functions and state objects. Using a class to store those values is much better for performance, as 95% of cases can be handled by providing the color as parameter. What's the use-case that it restricted for you?
m

Manuel Unterhofer

11/17/2023, 7:20 AM
That could have been achieved without removing the
interface
though, with a non-
@Composable
alternative to
ButtonDefaults.buttonColors()
, couldn’t it? That should yield the same performance? I’m currently designing a custom theme system and we’re trying to decide between the
interface
and
class
approach for us. The scenario we have in mind would be to set up custom animated transitions between the colors for arbitrary states or even to add additional states on any
Interaction
which are more complex than what `Indication`s can offer. For example, changing the border color on hover. For that purpose, we’d be passing an
InteractionSource
into all color state factories, like it is already done in most of
TextFieldColors
, even if not used by default. With a class, this option isn’t there anymore.
s

shikasd

11/17/2023, 12:17 PM
I am not sure you'd be able to collect an interaction source without a composable function though
m

Manuel Unterhofer

11/17/2023, 12:19 PM
No need, that would happen lazily as it already does in the color state factory, and those are also still there in Material 3:
The `Button`/`TextField` etc. call those internally on `ButtonColors`/`TextFieldColors` etc.
Those used to be part of the
interface
as well
s

shikasd

11/17/2023, 12:22 PM
Yeah, so we don't really wanna do that
you collect and update interactions at composition time, while creating extra states. this is heavier for compositions and invalidates everything whenever state changes
m

Manuel Unterhofer

11/17/2023, 12:23 PM
But this still happens in the material 3 implementation
s

shikasd

11/17/2023, 12:28 PM
correct, we are slowly phasing this out 🙂
m

Manuel Unterhofer

11/17/2023, 12:29 PM
Interesting. Any idea on what the new API will look like? It would make little sense for us to adopt this pattern if it’s about to change anyway. In fact, we had the same concerns about redundant collections and states but we thought it must be fine if Material 3 is still doing that 😅
s

shikasd

11/17/2023, 12:33 PM
It's likely that user-facing API is going to be more rigid, the same as you see in
ButtonColors
, as Material already handles many interactions internally. I assume that you are not really interested in some material aspects, so for you it might be easier to just customize
Surface
+ text or even
Box
+ text. Ideally, you'd avoid creating and memoizing intermediate states and just have state for color that is later used to invalidate draw pass
m

Manuel Unterhofer

11/17/2023, 1:15 PM
you collect and update interactions at composition time, while creating extra states.
I’m trying to understand this all the way. Am I right that the actual issue is that the color state will be read during composition, while passing it to the corresponding modifier as a parameter? Because setting up some state on initial composition is the only way to do that, isn’t it? And such a problem could be avoided with a draw modifier that takes a lambda for determining its inputs, including the color?
s

shikasd

11/17/2023, 1:18 PM
My comment is more about launching many effects and remembering many states for things that can be just a flow chain / suspend function Technically, if you are animating colors you probably want to
drawRect
in a draw modifier instead of invalidating composition with modifier
background
. If you are switching between discrete values, it should be fine though.
m

Manuel Unterhofer

11/17/2023, 1:31 PM
Understood, thanks for the thorough explanation!
4 Views