How to get Material3 primary/accent colors programmatically?

Viewed 344

Google introduced Material 3 which allows the user to choose a color to apply for the whole system theme, but their documentation isn't clear and didn't mention how to get current colors programmatically to use for the app such as changing a view's background color or text color.

E.g.: view.setBackgroundColor(Material3.getPrimaryColor());

Of course Material3.getPrimaryColor() doesn't exist and it is just an example of what I need.

Any help is appreciated, thanks.

1 Answers

First - bear in mind support for dynamic theming was added in Android 12 (API 31) and not all manufacturers support it yet, much less a compatibility implementation for lower versions.

Here is the documentation on how to use dynamic colors in general, including theme overlay and activity color overlay.

If you want to create themed views it's easier to use appropriate DynamicColor theme or at least wrapped context to inflate them and let them get stylized accordingly.

To just get specific colors you need to use last step - wrap a context with DynamicColors theme:

if (DynamicColors.isDynamicColorAvailable()) {
    // if your base context is already using Material3 theme you can omit R.style argument
    Context dynamicColorContext = DynamicColors.wrapContextIfAvailable(context, R.style.ThemeOverlay_Material3_DynamicColors_DayNight);
    // define attributes to resolve in an array
    int[] attrsToResolve = {
            R.attr.colorPrimary,    // 0
            R.attr.colorOnPrimary,  // 1
            R.attr.colorSecondary,  // 2
            R.attr.colorAccent      // 3
    };
    // now resolve them
    TypedArray ta = dynamicColorContext.obtainStyledAttributes(attrsToResolve);
    int primary   = ta.getColor(0, 0);
    int onPrimary = ta.getColor(1, 0);
    int secondary = ta.getColor(2, 0);
    int accent    = ta.getColor(3, 0);
    ta.recycle();   // recycle TypedArray

    // here you can consume dynamic colors
}
Related