158

I would like to store drawable resources' ID in the form of R.drawable.* inside an array using an XML values file, and then retrieve the array in my activity.

Any ideas of how to achieve this?

Andrew T.
  • 4,701
  • 8
  • 43
  • 62
gammaraptor
  • 1,886
  • 3
  • 14
  • 16

5 Answers5

383

You use a typed array in arrays.xml file within your /res/values folder that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <integer-array name="random_imgs">
        <item>@drawable/car_01</item>
        <item>@drawable/balloon_random_02</item>
        <item>@drawable/dog_03</item>
    </integer-array>

</resources>

Then in your activity, access them like so:

TypedArray imgs = getResources().obtainTypedArray(R.array.random_imgs);

// get resource ID by index, use 0 as default to set null resource
imgs.getResourceId(i, 0)

// or set you ImageView's resource to the id
mImgView1.setImageResource(imgs.getResourceId(i, 0));

// recycle the array
imgs.recycle();
M. Smith
  • 379
  • 1
  • 20
Patrick Kafka
  • 9,795
  • 3
  • 29
  • 44
  • defValue - Value to return if the attribute is not defined or not a resource. I'm pretty sure it will set the imageview blank if it has to use the default -1. http://developer.android.com/reference/android/content/res/TypedArray.html#getResourceId(int, int) – Patrick Kafka Sep 28 '13 at 00:31
  • 1
    For anyone else stuck on where exactly to put this arrays.xml file, I put it in res/values and things worked. I also had to rename it to array.xml instead of arrays, for some reason. – Tony Wickham Jul 17 '14 at 20:50
  • 1
    Is "string-array" correct? Shouldn't it just be "array"? – radley Sep 11 '14 at 20:02
  • http://developer.android.com/guide/topics/resources/string-resource.html#StringArray – Patrick Kafka Sep 11 '14 at 22:45
  • 9
    You should be using 0 instead of -1 for the default id. -1 is a valid resource id, while 0 is the null resource. – Alex Mar 24 '15 at 16:41
  • The correct element for a [TypedArray](http://developer.android.com/guide/topics/resources/more-resources.html#TypedArray) is `` not ``. – Lorne Laliberte Mar 09 '16 at 20:47
  • 1
    @Nishad **-1 stands for default value if index is catched with error**

    `getResourceId(int index, int defValue)`
    ***Retrieves the resource identifier for the attribute at index.***
    – KlevisGjN Mar 08 '17 at 12:11
  • 1
    Why do we have to use recycle at the end? – TheLearner Oct 12 '17 at 18:05
  • 3
    Use length() to get the element count for a TypedArray. – Roger Huang Dec 25 '17 at 08:09
  • IMO, using an `arrays.xml` file obscures the content. I personally add all my string arrays in a regular `strings.xml` file while I place my integer arrays in the `integer.xml` file. Actually, Android doesn't care how do you name all these resource files (you could even mix strings, styles, integers and everything in the same single file), so I prefer to make it clear what they contain. – thelawnmowerman Feb 03 '19 at 20:46
33

In the value folder create xml file name it arrays.xml add the data to it in this way

<integer-array name="your_array_name">
    <item>@drawable/1</item>
    <item>@drawable/2</item>
    <item>@drawable/3</item>
    <item>@drawable/4</item>
</integer-array>

Then obtain it to your code this way

private TypedArray img;
img = getResources().obtainTypedArray(R.array.your_array_name);

Then to use a Drawable of these in the img TypedArray for example as an ImageView background use the following code

ImageView.setBackgroundResource(img.getResourceId(index, defaultValue));

where index is the Drawable index. defaultValue is a value you give if there is no item at this index

For more information about TypedArray visit this link http://developer.android.com/reference/android/content/res/TypedArray.html

Ahmed Mostafa
  • 918
  • 1
  • 12
  • 20
17

You can use this to create an array of other resources, such as drawables. Note that the array is not required to be homogeneous, so you can create an array of mixed resource types, but you must be aware of what and where the data types are in the array.

 <?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="icons">
        <item>@drawable/home</item>
        <item>@drawable/settings</item>
        <item>@drawable/logout</item>
    </array>
    <array name="colors">
        <item>#FFFF0000</item>
        <item>#FF00FF00</item>
        <item>#FF0000FF</item>
    </array>
</resources>

And obtain the resources in your activity like this

Resources res = getResources();
TypedArray icons = res.obtainTypedArray(R.array.icons);
Drawable drawable = icons.getDrawable(0);

TypedArray colors = res.obtainTypedArray(R.array.colors);
int color = colors.getColor(0,0);

Enjoy!!!!!

yubaraj poudel
  • 3,821
  • 1
  • 31
  • 28
5

In Kotlin, you can do as:-

 <integer-array name="drawer_icons">
    <item>@drawable/drawer_home</item>
</integer-array>

You will get array of Image from the resource as TypedArray

 val imageArray = resources.obtainTypedArray(R.array.drawer_icons)

get resource ID by the index

imageArray.getResourceId(imageArray.getIndex(0),-1)

OR you can set imageView's resource to the id

imageView.setImageResource(imageArray.getResourceId(imageArray.getIndex(0),-1))

and in last recycle the array

imageArray.recycle()
Ved
  • 11,837
  • 5
  • 42
  • 60
Alok Mishra
  • 1,904
  • 1
  • 17
  • 18
2

kotlin way could be this:

fun Int.resDrawableArray(context: Context, index: Int, block: (drawableResId: Int) -> Unit) {
  val array = context.resources.obtainTypedArray(this)
  block(array.getResourceId(index, -1))
  array.recycle()
}

R.array.random_imgs.resDrawableArray(context, 0) {
  mImgView1.setImageResource(it)
}
Jan Rabe
  • 398
  • 2
  • 12