概要
res/values/arrays.xml 内部に drawable の array を作成した場合などに、resources の array 要素から resource ids を取得する extension です。
間違いの例
// drawable の resource id が返らず配列の各要素が 0 になる
val bannerImageResourceIds: IntArray =
resources.getIntArray(R.array.banner_drawables)
使用例
res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="banner_drawables">
<item>@drawable/banner_0</item>
<item>@drawable/banner_1</item>
<item>@drawable/banner_2</item>
</array>
</resources>
R.array.banner_drawablesからdrawableのid群を取得する
val bannerImageResourceIds: IntArray =
resources.getIds(R.array.banner_drawables)
ソース
/**
* Returns resource ids from the array resource id.
*/
fun Resources.getIdList(arrayResourceId: Int): List<Int> {
with(obtainTypedArray(arrayResourceId)) {
try {
return (0 until length()).map { getResourceId(it) }
} finally {
recycle()
}
}
}
/**
* Returns resource ids from the array resource id.
*/
fun Resources.getIds(arrayResourceId: Int): IntArray {
return getIdList(arrayResourceId).toIntArray()
}
/**
* Returns the resource id.
* @throws IllegalStateException when the resource id does not exist.
*/
fun TypedArray.getResourceId(index: Int): Int {
return getResourceId(index, 0).apply { if (this == 0) throw IllegalStateException("resourceId not found.") }
}
あとがき
Android では Bundle でプリミティブの配列を使うことが多いので IntArray を使うケースが多いように思えます。しかし List で扱う際に toList() を呼ぶのがめんどくさいので両方作ってみました。ちゃんと作るなら、IntArray 版は生成時に List を介在させないようにしたほうがよさそうですね。