views:

236

answers:

6

hello,

I want to display a random image from the bunch of images i have stored in res/drawable.

The only technique that I know is to access a particular image if you know its resource id. Is there a way to access the images by using the filenames or something else (which can be constructed at runtime)?

I want to randomly select an image at runtime. Any suggestions/ideas appreciated :)

Thanks Chinmay

+1  A: 

I can't think of anything you can do at runtime. You could possibly create an array of address integers (since the R.drawable.xxxx is essentially an integer address) and then use java.util.Random to select a random resource address from your array.

bporter
I did think of this...but I dont want to change the code everytime i add a few images to my res/ directory.
coldskull
I believe Mayra has the answer.
bporter
+1  A: 

The items in res/drawable are enumerated in the R.drawable class at compile time. You could probably use reflection to get a list of the members of that class, and then select from that list randomly.

Mayra
I just tried this out and was able to obtain a list of resource names - just one more step would be required to return their value. I was able to see that reflection worked. Great suggestion Mayra! Here's the line of code to get field names: java.lang.reflect.Field[] fields = R.drawable.class.getFields();
bporter
A: 

If you knew you had X images to choose from could use random.nextInt(X) to randomly generate an integer between 0 (inclusive) and X (exclusive), then switch on it to pick your resource:

Random mRand = new Random();
            int x = mRand.nextInt(8);
            switch (x) {
            case 0:
                mResource = R.id.someresource1
            case 1:
                mResource = R.id.someresource2
            ...
            case X:
                mResource = R.id.someresourceX

            }
QRohlf
This is essentially a more complicated way of doing what bporter suggested, I would recommend using that method instead, it's tidier.
QRohlf
A: 

I have never used the AssetManager, but would you be able to call getAssets on your Resources class, and then call list on the AssetManager with the location of your resources?

Marc
A: 

If you don't mind setting up a <level-list> XML file, you should be able to use a LevelListDrawable and call setImageLevel() with your random number.

If you don't want to change this list when you add files, I would assume there is some way of setting up a build event where you could progmatically generate this file.

Andrew Koester
A: 

You can also access resources by name, which may be a viable approach to solving your problem if you know the names of the resources or can derive them according to some pre-defined naming scheme.

You have to map the name to the identifier using the getIdentifier method of the Resources class.

String name = "resource" + rng.nextInt(count);
int resource = getResources().getIdentifier(name, "drawable", "com.package");

The documentation for this method says:

Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.

This is true but need not be a problem if you are doing it in code that isn't performance sensitive.

Alternatively, if you don't mind listing the resources in XML, you could create a typed array that you can then randomly select from.

Dan Dyer