Skip to main content

Android Dynamic Color

Special utility in Android platform since Android 12 (SDK 31), that Google introduced Material Design 3 a.k.a Material You, and brought their APIs for enabling users to personalize their color experience in your app from user personal wallpaper or through selected color variants in the wallpaper picker

import {
AndroidDynamicColor,
} from "material-color-react-native"

if(AndroidDynamicColor.isAvailable()) {

const androidColor = new AndroidDynamicColor()

console.log(
androidColor.colorScheme.primary,
androidColor.colorScheme.onPrimary,

androidColor.colorScheme.primaryPalette.keyColor,
androidColor.colorScheme.primaryPalette.tone(70),
)

}
warning

Android Dynamic Color is available only for Android app and for Android SDK 31 (Android 12) or latest. Make sure that you are using the isAvailable static method.

See functional compatibility to keep cross platform works.

Light or Dark Scheme

The AndroidDynamicColor class here is not using the Appearance from React Native to determine whether the app is in dark or light color scheme. In this module, we let Android decide internally through their configuration.

Fortunately, if you want to get only one of it, or both light and dark scheme, you can still pass the dark option to the class constructor

const androidColor = new AndroidDynamicColor({
isDark: true, // or false
// if undefined, we let Android decide
})
info

If the isDark option is undefined, and then you are using Expo, the userInterfaceStyle (from expo-system-ui) configuration or probably other frameworks configuration would be ignored, because the dark or light theme is determined by Android Configuration UI Mode.

Functional Compatibility

AndroidDynamicColor provides an instance as similar as possible to the MaterialColor, so you can easily access and seamless integration. The main difference is that we can't get the source color from Android Dynamic Color, it's simply because no Android API provides it.

Then, if Android Dynamic Color is not available in user device, you can use MaterialColor as a fallback if it does.

import {
AndroidDynamicColor,
MaterialColor,
} from "material-color-react-native"

const androidDynamicColor = AndroidDynamicColor.isAvailable()
? new AndroidDynamicColor()
: null

const materialColor = new MaterialColor("#ffde3f")

// same object
const colorScheme = androidDynamicColor?.colorScheme ?? materialColor.colorScheme

const primary = colorScheme.primary

As an alternative, and probably better, you can use the useAndroidDynamicColorCompat

You can also see full example here at this project repository

React Hooks

useAndroidDynamicColor

Simple React Hooks for you to get Android Dynamic Color but in React Hooks style

import {
useAndroidDynamicColor,
} from "material-color-react-native"

export function YourReactComponent() {

const androidDynamicColor = useAndroidDynamicColor()

console.log(
androidDynamicColor.colorScheme.primary,
androidDynamicColor.colorScheme.onPrimary,

androidDynamicColor.secondaryPalette.keyColor,
androidDynamicColor.secondaryPalette.tone(80),
)

}

This hook is using the useColorScheme hook from React Native. It's decided internally if it's return in dark or light mode, but you can still override the option by providing the argument to the useAndroidDynamicColor.

useAndroidDynamicColorCompat

Alternatively, you can use useAndroidDynamicColorCompat in your React component to get Material color for non Android platform and older Android SDK by giving a source color to build MaterialColor as fallback if it does

import {
useAndroidDynamicColorCompat,
} from "material-color-react-native"

export function YourReactComponent() {

const materialColor = useAndroidDynamicColorCompat("#ffde3f")

console.log(
materialColor.colorScheme,
materialColor.primaryPalette.keyColor,
)

}

You can see full example here at this project repository

Definitions

See definitions