Reputation: 2044
I was used to override XML resources in values within specific app variants but i cannot do that anymore in jetpack compose so i was wondering which is a good approach with the new library without using any XML at all.
My theming is in a module and that module doesn't know anything about the app variants and i would like it to stay so. Which means that i cannot create a AppVariantColors class for each variant since i would not be able to reference it.
Should i pass the palette to the theme composable?
EDIT: what i am doing now is the following:
First i define a palette class with a set of color variants i will then use in the real variants:
enum class AppColorPalette {
DARK_BLUE,
DARK_RED,
LIGHT_BLUE,
LIGHT_RED
}
Then i create an app theme passing the palette
@Composable
fun AppTheme(
dims: AppDims = appDims(),
palette: AppColorPalette = AppColorPalette.DARK_BLUE,
colors: AppColors = appColors(colorPalette = palette),
typography: AppTypography = appTypography(colors, dims),
shapes: AppShapes = appShapes(),
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
LocalAppColors provides colors,
LocalAppDims provides dims,
LocalAppShapes provides shapes,
LocalAppTypography provides typography,
) {
MaterialTheme(
colors = colors.materialColors,
typography = typography.materialTypography,
shapes = shapes.materialShapes,
content = content,
)
}
}
Finally i create app Colors composable based on the palette
@Composable
fun appColors(colorPalette: AppColorPalette): AppColors = when (colorPalette) {
AppColorPalette.DARK_BLUE -> darkAppColorsBlueVariant
...
}
Where colors are defined something like this:
private val darkAppColorsBlueVariant = darkAppColors.copy(
highEmphasis = AppColorsPalette.WhiteA100,
midEmphasis = AppColorsPalette.WhiteA50,
materialColors = darkColors(
primary = AppColorsPalette.DarkGrey900,
)
)
Basically doing so i can use the BuildConfig approach having to just select the color variant based on the theme
Upvotes: 2
Views: 2124
Reputation: 364730
You can use the same approach.
Just config your build variant or product flavor in the build.gradle file then in your module define the MaterialTheme
object (using for example the Themes.kt
file in the different modules):
MaterialTheme(
colors = …,
typography = …,
shapes = …
) {
// app content
}
Or use your approach described in the updated question, using a single MaterialTheme object with the different colors defined in the single variants.
Upvotes: 1
Reputation: 8467
One way could be through BuildConfig
fields on your build.gradle
(app) file.
First define your flavors:
android {
// other stuff
flavorDimensions "base"
productFlavors {
cocacola {
dimension "base"
// cocacola is red :)
buildConfigField "int", "accentColor", "0xFF0000"
}
pepsi {
dimension "base"
// pepsi is blue
buildConfigField "int", "accentColor", "0x00FF00"
}
}
}
This will autogenerate a BuildConfig.java
that you can access through Kotlin:
public final class BulildConfig {
public static final int accentColor = 0xFF000; // depending on the flavor built
}
Then you can reference this static values from the place you define the material theme similar to how @Philip Dukov suggested
private val AppPalette = lightColors(
accent = Color(BuildConfig.accentColor)
)
MaterialTheme(
colors = AppPalette,
typography = …,
shapes = …,
content = …
)
Upvotes: 0