Dan Artillaga
Dan Artillaga

Reputation: 1955

Color object that changes with dark mode like MaterialTheme.colors, but with my own app's custom colors

How can I have a custom color object for my app that changes alongside isSystemInDarkTheme(). I want to achieve something like MaterialColors.colors.primary but with custom colors for my app.

I want to use it like this:

@Composable
fun MyView() {
    Surface(color = MyAppColors.CustomColor /*Color changes when isSystemInDarkTheme() changes*/) {
        ...
    }
}

Upvotes: 1

Views: 223

Answers (1)

Phil Dukhov
Phil Dukhov

Reputation: 88467

  1. You can declare colors one by one using isSystemInDarkTheme
object MyAppColors {
    val CustomColor: Color
        @Composable
        @ReadOnlyComposable
        get() = if (isSystemInDarkTheme()) {
            Color.Red
        }
        else {
            Color.Gray
        }
}
  1. Fully duplicate MaterialTheme logic for your colors. I think that't the right way and more performant one:
object MyAppColors {
    val YourPrimary: Color
        @Composable
        @ReadOnlyComposable
        get() = LocalColors.current.yourPrimary
}

data class CustomColors(
    val yourPrimary: Color,
)

val DarkThemeColors = CustomColors(
    yourPrimary = Color.Red
)

val LightThemeColors = CustomColors(
    yourPrimary = Color.Gray
)

val LocalColors = staticCompositionLocalOf { LightThemeColors }

@Composable
fun ComposeTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable() () -> Unit
) {
    val colors = if (darkTheme) {
        DarkThemeColors
    } else {
        LightThemeColors
    }

    CompositionLocalProvider(
        LocalColors provides colors
    ) {
        content()
    }
}

Usage:

setContent {
    ComposeTheme {
        Surface(color = MyAppColors.YourPrimary, ...)
    }
}

Upvotes: 2

Related Questions