'Android Jetpack Compose(Composable) Change Theme Color Smoothly
Since I don't want to use the base Colors class, instead I want to use my own colors that are not used in neither buttons or text elements. So I created my own Colors class with the corresponding light and dark palette classes. Then in my composable I want to change the theme color, but using animation, this is why I used animateColorAsState, but the code looks very ugly. Is there a way to animate all the colors, without defining animateColorAsState for each color separately?
Code for the custom color palettes
@Stable
class Colors(
background: Color,
line90DegColor: Color,
hoursArrowColor: Color,
secondsArrowColor: Color,
baseColor: Color,
lighter: Color,
darker: Color,
baseColorLessTransparent: Color,
baseColorSemiTransparent: Color,
baseColorTransparent: Color
) {
var background by mutableStateOf(background, structuralEqualityPolicy())
internal set
var line90DegColor by mutableStateOf(line90DegColor, structuralEqualityPolicy())
internal set
// same for the rest of the colors
}
val LightColorPalette = Colors(
background = Color(0xFFECECF3),
line90DegColor = Color(0xFF9B9BB0),
// same for the rest of the colors
)
val DarkColorPalette = Colors(
background = Color(0xFF25252D),
line90DegColor = Color(0xFF9B9BB0),
// same for the rest of the colors
)
Code for the composable, where the colors are changes via animateColorAsState
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var isLightTheme by remember {
mutableStateOf(true)
}
val colors = if (isLightTheme) {
LightColorPalette
} else {
DarkColorPalette
}
// create color state for each of the theme color
val animationSpec: AnimationSpec<Color> = tween(durationMillis = 1500)
val background by animateColorAsState(colors.background, animationSpec)
val line90DegColor by animateColorAsState(colors.line90DegColor, animationSpec)
val hoursArrowColor by animateColorAsState(colors.hoursArrowColor, animationSpec)
val secondsArrowColor by animateColorAsState(colors.secondsArrowColor, animationSpec)
val baseColor by animateColorAsState(colors.baseColor, animationSpec)
val lighter by animateColorAsState(colors.lighter, animationSpec)
val darker by animateColorAsState(colors.darker, animationSpec)
val baseColorLessTransparent by animateColorAsState(colors.baseColorLessTransparent, animationSpec)
val baseColorSemiTransparent by animateColorAsState(colors.baseColorSemiTransparent, animationSpec)
val baseColorTransparent by animateColorAsState(colors.baseColorTransparent, animationSpec)
// create new Colors object that matches the current theme
val animatedColors = Colors(
background,
line90DegColor,
hoursArrowColor,
secondsArrowColor,
baseColor,
lighter,
darker,
baseColorLessTransparent,
baseColorSemiTransparent,
baseColorTransparent
)
ClockWidget(animatedColors, hours, minutes, seconds) {
isLightTheme = !isLightTheme
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

