0

I have been exploring Compose + Material 3 for the first time and I am having a really hard time trying to implement a custom color.

What I mean by this is doing the following based on how things could be done before Compose:

I have my custom attribute in attrs.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="CustomStyle">
        <attr name="myCustomColor"
            format="reference|color"/>
    </declare-styleable>
</resources>

And that custom attribute can be used in my light and dark styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="myCustomColor">@color/white</item> <!-- @color/black in the dark style config -->
    </style>
</resources>

And then I can use it anywhere I want, both in code or in layouts:

<com.google.android.material.imageview.ShapeableImageView
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:background="?myCustomColor"

This is very simple and practical because it resolves the light and dark color automatically and all I need is to use the custom color reference.

But in Compose with Material 3 I can't find anywhere explained how something like this can be done.

In Material 2 it was possible to something like this:

val Colors.myExtraColor: Color
    get() = if (isLight) Color.Red else Color.Green

But in Material 3 this is no longer possible:

Unlike the M2 Colors class, the M3 ColorScheme class doesn’t include an isLight parameter. In general you should try and model whatever needs this information at the theme level.

https://developer.android.com/jetpack/compose/designsystems/material2-material3#islight

I tried looking for a solution here in SO but so far found nothing that would work for this.

Is there a simple way of achieving this like it is possible with the non-Compose version as I exemplified above?

Shadow
  • 4,168
  • 5
  • 41
  • 72
  • `CompositionLocalProvider` is what are you looking for, this [answer](https://stackoverflow.com/a/75557863/18943404) can help you to achieve that. The example was written with M2, but it is independent of it, it will work the same in M3 and can even be used for other things, like `dp`, `Shapes`, etc. – Thales Isidoro Sep 02 '23 at 00:47
  • @ThalesIsidoro But that suggestion means I will no longer be able to use default references such as `MaterialTheme.colorScheme.background`, right? Or it allows both to be used without issue? I already have a `lightColorScheme`/`darkColorScheme` configured, but your suggestion appears to be incompatible with this, as in it's either one or the other. – Shadow Sep 02 '23 at 00:59
  • [CompositionLocalProvider](https://developer.android.com/jetpack/compose/compositionlocal) is not a replacement, you can still use the others color's reference. A solid example of that is [NowInAndroid](https://github.com/android/nowinandroid/blob/main/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Theme.kt#L236) whit the same thing (customs colors). – Thales Isidoro Sep 02 '23 at 08:39

0 Answers0