I have colors stored as IntArrays this is a simple function to convert to the argb color value used by Android.
fun IntArray.toColor(): UInt {
var color: Long = 0xFF000000
val maxIndex = size - 1
this.withIndex().forEach { (index, value) ->
color = color or (value.toLong() shl (8 * (maxIndex - index)))
}
return color.toUInt()
}
If you look at Android's own source code, you'll find color notation expressed as below
...
@ColorInt public static final int RED = 0xFFFF0000;
@ColorInt public static final int GREEN = 0xFF00FF00;
@ColorInt public static final int BLUE = 0xFF0000FF;
...
If I try to use the same value e.g. 0xFFFF0000 as Kotlin Int it's not possible, says the literal doesn't conform to the type Int. So I use UInt in my method.
Android's own code(in Java) android.graphics.Paint.setColor(@ColorInt int color) requires int and in my Kotlin Code I can only use and Int and not a UInt and when I use UInt.toInt() the value gets messed up.
Example
val color = arrayOf(0x11, 0x22, 0x33).toIntArray().toColor()
print(color.toString(16)) // ff112233 (UInt)
print(color.toInt().toString(16)) // -eeddcd (Int)
How do I convert any Kotlin type larger then Int to Int with the value intact?
Is it possible to solve this without calling Java in Kotlin?
Thanks
Kotlin Int should work well. Have you tried to use this value as color? Nevermind that color.toInt().toString(16) returns -eeddcd. It should return that because Int value dedicates highest bit for sign. That's representation issue, but the actual value is 0xff112233. So Kotlin Int with value -eeddcd when you pass it to setColor should look same as 0xff112233.
So try implement your function Int.toColor as follows:
fun IntArray.toColor(): Int {
var color: Int = 0xFF000000.toInt()
val maxIndex = size - 1
this.withIndex().forEach { (index, value) ->
color = color or (value shl (8 * (maxIndex - index)))
}
return color
}
I have tested the colors in working code. It's working fine, the issue is in Kotlin's string representation.
User contributions licensed under CC BY-SA 3.0