BattleProgrammerShibata

ある日は誰かと戦い、ある日は何かと戦い、そしてある日は自分と戦うのだろう、そういう生き物。

Color.parseColor に短縮形の16進数カラーコードが食わせられなかったのでカラーコードを正規化するコード書いた #Android #Kotlin

Layout や Widget に対して背景や文字列の着色をしようとした場面で # から始まる短縮形16進数カラーコード(#333 とか #fff)を Color.parseColor に食わせた結果を設定したのだが色が付くどころか文字列すら表示されなくなってアレって思ってログ見たっけ Exception スローされちゃってもう実行時エラーさ。

短縮形は食わせられないみたい

developer.android.com

メソッド実装ぼけっと眺めてたけれど短縮形は想定してない実装なのかなー? って感じで、このメソッドに渡す前に短縮形の16進数カラーコードは6桁に正規化する必要があることが分かった。で、軽く調べた感じそれを実現する標準なものはなく自前実装してみたのがこれ。

コード(Kotlin)

/**
 * "#" を prefix にする16進数カラーコード文字列を正規化する。
 * 16進数カラーコード文字列の文字列長が4の場合は正規化処理を施したものが返却される。
 * そうでない場合は、そのまま返却される。
 *
 * @param hexColorString # を prefix にする16進数カラーコード文字列
 */
fun getNormalizedHexColorString(hexColorString: String): String {
    // # を prefix にする文字列形式を想定しているため "# + 3桁英数字" の文字列長から4としている。
    val threeDigitHexColorStringLength = 4
    var normalizedHexColorString = "#"

    if (hexColorString.length != threeDigitHexColorStringLength) {
        return hexColorString
    }

    // ここダサすぎでは
    hexColorString.removeRange(0, 1)
        .forEach { c ->
            normalizedHexColorString += "$c$c"
        }

    return normalizedHexColorString
}

もちっとシンプルに実現できる気もする。