65

How to parse hex string e.g. #9CCC65 in Color class in jetpack compose.

P.S: option seem to be missing in jetpack compose package


Current Workaround: Exported parseColor() method from standard Color class.

@ColorInt
fun parseColor(@Size(min = 1) colorString: String): Int {
    if (colorString[0] == '#') { // Use a long to avoid rollovers on #ffXXXXXX
        var color = colorString.substring(1).toLong(16)
        if (colorString.length == 7) { // Set the alpha value
            color = color or -0x1000000
        } else require(colorString.length == 9) { "Unknown color" }
        return color.toInt()
    }
    throw IllegalArgumentException("Unknown color")
}
Vipul Asri
  • 8,903
  • 3
  • 46
  • 71
  • 6
    Parse the hex string into a `Long`. Pass that `Long` into the `Color()` function. – CommonsWare Feb 16 '20 at 12:04
  • @CommonsWare tried exporting the `parseColor()` method from standard Color class. As its working fine for now, but I think jetpack compose team should add this method. – Vipul Asri Feb 16 '20 at 12:13
  • @CommonsWare tried your solution as well, having `java.lang.NumberFormatException` exception. – Vipul Asri Feb 16 '20 at 12:15
  • If you literally tried parsing `#9CCC65`, that will not work, as `#` is not part of a number. The algorithm is pretty much what you see there with `parseColor()`. I won't argue if the Compose team adds support for color strings like this, but I also would not be surprised if they decide that this is out of scope and can be handled easily enough by apps, or by some other non-Compose library. – CommonsWare Feb 16 '20 at 12:40
  • @CommonsWare yeah got your point. Thanks! – Vipul Asri Feb 16 '20 at 12:42

8 Answers8

85

Instead of passing as String instead pass as Hexadecimal. For example if you want this #9CCC65 Color just remove the front # and replace it with 0xFF. Example

val PrimaryBlue = Color(0xFF9CCC65)
Mayank Wadhwa
  • 1,673
  • 17
  • 20
53

You can use this object class with a getColor method.

object HexToJetpackColor {
    fun getColor(colorString: String): Color {
            return Color(android.graphics.Color.parseColor("#" + colorString))
    }
}

Or we can use an extension function

fun Color.fromHex(color: String) = Color(android.graphics.Color.parseColor("#" + colorString))

Jetpack Color class i.e androidx.ui.graphics.Color only takes RGB, ARGB, ColorSpace and colorInt in constructor. See: Color.kt

so, here we are directly accessing parseColor() method from android.graphics.Color which returns colorInt.

Hence parseColor() method can be used to get colorInt and then providing it to Jetpack Color class to get androidx.ui.graphics.Color object.

Vipul Asri
  • 8,903
  • 3
  • 46
  • 71
burkinafaso3741
  • 1,000
  • 1
  • 10
  • 15
  • 4
    Or maybe you can add an extension function in your project. fun Color.fromHex(color: String) = Color(android.graphics.Color.parseColor("#" + colorString)) – facundomr Sep 10 '20 at 04:05
  • 2
    @facundomr Well you should use Color.Companion instead of just Color, to use it in `Color.fromString()` form. – Tura Dec 02 '21 at 12:57
19

Similar to Int.dp, there can be String.color extenstion property.

val String.color 
    get() = Color(android.graphics.Color.parseColor(this))

This can be used as member property on color hex String.

"#FF0000".color
Om Kumar
  • 1,404
  • 13
  • 19
14

I also had this problem and I finally found the solution:

    val myColorString = "#B00020"
    val myComposeColorInt = Color(myColorString.toColorInt())
Tob237
  • 291
  • 1
  • 5
  • 15
12

How about solution not dependant on Android? #KMP

val hashColorString = "#00AB18"
val color = Color(hashColorString.removePrefix("#").toLong(16) or 0x00000000FF000000)
Majkeee
  • 960
  • 1
  • 8
  • 28
11

Another option is to write an extension function similar to how android.graphics.Color works:

import androidx.compose.ui.graphics.Color

fun Color.Companion.parse(colorString: String): Color =
    Color(color = android.graphics.Color.parseColor(colorString))

Then you can write your compose like this:

Modifier.background(Color.parse("#FF0000"))
Chris
  • 1,180
  • 1
  • 9
  • 17
10

hex string to color [this extension function is available inside android sdk ]

Color("#FFFFFF".toColorInt())

incase if u want to convert back to hex code

fun Color.toHexCode(): String {
    val red = this.red * 255
    val green = this.green * 255
    val blue = this.blue * 255
    return String.format("#%02x%02x%02x", red.toInt(), green.toInt(), blue.toInt())
}

incase if u also want alpha value

fun Color.toHexCodeWithAlpha(): String {
            val alpha = this.alpha*255
            val red = this.red * 255
            val green = this.green * 255
            val blue = this.blue * 255
            return String.format("#%02x%02x%02x%02x", alpha.toInt(),red.toInt(), green.toInt(), blue.toInt())
        }
Abhijith mogaveera
  • 918
  • 10
  • 16
1

If you want to avoid having to import android.graphics.Color, here's another straightforward alternative:

val hexString = "#f8f8f2"
Color(("ff" + hexString.removePrefix("#").lowercase()).toLong(16))

Color in this case would be immediately the one from androidx.compose.ui.graphics.Color.

haikalpribadi
  • 424
  • 1
  • 7
  • 19
  • This doesn't work. Try it with "#ffffff" and you won't get white. – Bartek Jul 08 '22 at 06:42
  • I just tried it with `ffffff` and `#ffffff`, and they both work, @Bartek. The white colour was shown. This is the exact code I'm running: `fun hexToColor(hexString: String): Color { return Color(("ff" + hexString.removePrefix("#").lowercase()).toLong(16)) }` Are you sure you didn't make a mistake elsewhere in your code? – haikalpribadi Sep 23 '22 at 11:02
  • the answer got fixe and now it works correctly – Bartek Sep 24 '22 at 17:41
  • It's working. Thank you! – NightFury Aug 12 '23 at 23:24