The material 3 site has a section on custom colors.
Is there a way to programmatically generate tonal palettes for a given (harmonized) color to override the color scheme?
@Composable
fun CardMinimalExample(
customColor: Color = Color.Red
) {
MaterialTheme(
colorScheme = MaterialTheme.colorScheme.copy(
surfaceVariant = customColor
)
) { // inefficient?
Card() {
Text(text = "Hello, world!")
}
}
}
@Preview
@Composable
private fun Preview() {
CardMinimalExample()
}
I found the following restricted method Hct.fromInt
that seems to work.
@SuppressLint("RestrictedApi")
@ColorInt
fun getColorRole(@ColorInt color: Int, @IntRange(from = 0, to = 100) tone: Int): Int {
val hctColor = com.google.android.material.color.utilities.Hct.fromInt(color)
hctColor.tone = tone.toDouble()
return hctColor.toInt()
}
val hexColor = java.lang.String.format("#%08X", -0x1 and color.toArgb())
Toast
.makeText(
context,
hexColor,
Toast.LENGTH_SHORT
)
.show()
Here is a library built on this method.
data class CustomColorScheme(
val color: Color,
val onColor: Color,
val colorContainer: Color,
val onColorContainer: Color
)
fun Color.lightCustomColorScheme(): CustomColorScheme {
val palette = tonalPalette()
return CustomColorScheme(
color = palette.color40,
onColor = palette.color100,
colorContainer = palette.color90,
onColorContainer = palette.color10
)
}
fun Color.darkCustomColorScheme(): CustomColorScheme {
val palette = tonalPalette()
return CustomColorScheme(
color = palette.color80,
onColor = palette.color20,
colorContainer = palette.color30,
onColorContainer = palette.color90
)
}