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

Archie

09/30/2020, 8:09 AM
Hi @nickbutcher, may I ask a question about theming in compose. I have a situation where my primary color shouldn't be used for components that by default uses the primary color. for example: my primay color is Red so when using TextField, its active color defaults to Red. But I don't want it red but instead I need its active color to be Blue. If I understand it correctly, I would just have to create my own TextField and replace the active color. But then I look into Composable functions that create TextField and there are two. I would then have to have my own version of these two TextField Composable function with the overriden active color to Blue. It was fine here since there are only two functions I have to modify, but I was thinking what if there was more than two of these function or maybe in the future there may be additional of these functions. Is this the correct way to approach this problem?
n

nickbutcher

09/30/2020, 8:43 AM
There are 3 possible approaches here: 1. Specify a different
activeColor
at call sites 2. Wrap the
TextField
composable(s) in your own composable which configures the
activeColor
param to something else and use your composable throughout. 3. Create a 'theme overlay' another theme the sets
primary
to your blue color and wrap components that don't want to use the red primary in that. cc @Louis Pullen-Freilich [G]
1. Would get pretty tedious and error prone
2. Would look like this:
Copy code
@Composable fun MyTextField(
  // copy all params from TextField
  activeColor: Color = // your blue color,
) {
  TextField(
    // forward on params
  )
}
Then you have to use this throughout. You'd obviously have to do this for all composables which you want to change the default color.
3. Would looks like this: Define two themes
Copy code
@Composable fun RedTheme(…) {
  MaterialTheme(
    …
    colors = redColors
  )
}

@Composable fun BlueTheme {
  MaterialTheme(
    colors = blueColors
  )
}
Then use the
RedTheme
for most of the app but in places you want to deviate, wrap them:
Copy code
…
BlueTheme {
  TextField(…)
}
❤️ 4
👍 5
a

Archie

09/30/2020, 9:35 AM
@nickbutcher, Thank you very much. I am actually using approach 2. My only concern is it could be very tedious to maintain as Compose Grow. But maybe that how it is. Thank you very much for the info.
n

nickbutcher

09/30/2020, 10:19 AM
I think of 2 as the equivalent of an xml style. Let us know how you get on
❤️ 4
y

Yann Badoual

10/01/2020, 10:13 AM
Reading this gave me an idea of external lib that could be useful (or not). An annotation processor for a
@ComposableAlias
annotation that you could set on a function, and said function would define only parameter that you want to override default value for. And it would generate the content, not having to keep the signature up to date each time to composable changes. ie:
Copy code
@ComposableAlias("TextField")
fun CustomTextField(
   activeColor: Color = myCustomActiveColor
){
    // Empty
}
And it would generate a full composable with complete signature for each
TextField
function having an
activeColor
parameter
a

Archie

10/01/2020, 10:15 AM
I think thats a good idea..
y

Yann Badoual

10/01/2020, 11:54 AM
Tried to implement it, but I'm having an issue, the annotation processor lib won't return the methods if one of the argument is not in the processor's classpath. And I can't import compose in a java-lib. And making it an android-lib won't work because then I don't have the
AbstractProcessor
class in the classpath 🤷‍♂️
c

Colton Idle

03/14/2021, 7:28 PM
@nickbutcher I followed your Option 3 today and it worked flawlessly, but I wasn't able to find this pattern in the docs. Unless I'm looking in the wrong places. Is this still the preferred route? It just makes a lot of sense and is simple.
2 Views