Android conflict between Kotlin Int and Java int representation

0

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

android
kotlin
canvas
asked on Stack Overflow Mar 29, 2021 by jasxir • edited Mar 29, 2021 by jasxir

2 Answers

1

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
}
answered on Stack Overflow Mar 29, 2021 by 0awawa0
0

I have tested the colors in working code. It's working fine, the issue is in Kotlin's string representation.

answered on Stack Overflow Mar 29, 2021 by jasxir

User contributions licensed under CC BY-SA 3.0