I want to display images randomly when my activity starts. I am using the following code to execute it.
final ImageView img = (ImageView) findViewById(R.id.imgRandom);
final String str = "img_" + rnd.nextInt(2);
img.setImageDrawable(getResources().getDrawable(
getResourceID(str, "drawable", getApplicationContext())));
}
protected final static int getResourceID(final String resName,
final String resType, final Context ctx) {
final int ResourceID = ctx.getResources().getIdentifier(resName,
resType, ctx.getApplicationInfo().packageName);
if (ResourceID == 0) {
throw new IllegalArgumentException(
"No resource string found with name " + resName);
} else {
return ResourceID;
}
}
PROBLEM: This code only randomly generates first two images present in my drawable, whereas i have a total of 8 images.
Thanks in advance.
P.S the name of my images are img_0 , img_1, img_2, img_3, img_4, img_5, img_6, img_7
Use HashMap to store your image names associated with a key ,
HashMap<Integer, String> meMap=new HashMap<Integer, String>();
meMap.put(0,"img_0"); // add other images as 1, 2, 3
Use Random class to generate number including 0 and less than 8
Random rnd = new Random();
int value = rnd.nextInt(8);
Get the relevant map object according to the generated key(random integer) and get the respective image name and load it.
Related
I'm circulating some drawable images (fx. I have a few images named image_1, image_2 etc.) as header images in a fragment. The images are loaded randomly as I hardcode the number of images available for me, and generate a random index from 0 to this number.
mHeaderBackgroundImagesCount is a final:
private int getHeaderBackground() {
// Random index between 0 and mHeaderBackgroundImagesCount
Random rand = new Random();
int index = rand.nextInt(mHeaderBackgroundImagesCount) + 1;
return getResources()
.getIdentifier("image_" + index, "drawable", getPackageName());
}
As hard coding anything isn't normally the way to go in correct programming, I therefore like to dynamically find out how many 'image_X' drawables I have and set it to mHeaderBackgroundImagesCount.
I would like to do the same with strings from the strings.xml resource file as I'm also circulating some strings on every page load.
Solution Update
This update is inspired by Lalit Poptani's suggestion below. It includes syntax corrections and optimizations and have been tested to work.
private int countResources(String prefix, String type) {
long id = -1;
int count = -1;
while (id != 0) {
count++;
id = getResources().getIdentifier(prefix + (count + 1),
type, getPackageName());
}
return count;
}
System.out.println("Drawables counted: " + countResources("image_", "drawable"));
System.out.println("Strings counted: " + countResources("strTitle_", "string"));
Note: This method assumes that the resources counted start with index 1 and have no index holes like image_1 image_2 <hole> image_4 etc. because it will terminate on first occasion of id=0 thus resulting a faulty count.
If you are sure that your list of drawables will be in a sequence of image_1, image_2,... and so on then you can apply below logic,
int count = 0;
int RANDOM_COUNT = 10; //which is more than your drawable count
for (int i = 1; i < RANDOM_COUNT; i++){
int id = getResources().getIdentifier("ic_launcher_"+i,
"drawable", getPackageName());
if(id != 0){
count = + count;
}
else{
break;
}
}
Log.e(TAG, "This is your final count of drawable with image_x - "+ count);
You use this logic because of there will be no drawable with any name as image_x then id will be 0 and you can break the loop
I am not sure if it's possible to dynamically get the number of resources or drawables.
A way to circumvent this issue is to use string arrays as resources in strings.xml.
e.g.
<resources>
<string-array name="foo_array">
<item>abc1</item>
<item>abc2</item>
<item>abc3</item>
</string-array>
int count = getResources().getStringArray(R.array.foo_array).length;
I would like to change the imageview src based on my string, I have something like this:
ImageView imageView1 = (ImageView)findViewById(R.id.imageView1);
String correctAnswer = "poland";
String whatEver = R.drawable+correctAnswer;
imageView1.setImageResource(whatEver);
Of course it doesnt work. How can I change the image programmatically?
public static int getImageId(Context context, String imageName) {
return context.getResources().getIdentifier("drawable/" + imageName, null, context.getPackageName());
}
use:
imageView1.setImageResource(getImageId(this, correctAnswer);
Note: leave off the extension (eg, ".jpg").
Example: image is "abcd_36.jpg"
Context c = getApplicationContext();
int id = c.getResources().getIdentifier("drawable/"+"abcd_36", null, c.getPackageName());
((ImageView)v.findViewById(R.id.your_image_on_your_layout)).setImageResource(id);
I don't know if this is what you had in mind at all, but you could set up a HashMap of image id's (which are ints) and Strings of correct answers.
HashMap<String, Integer> images = new HashMap<String, Integer>();
images.put( "poland", Integer.valueOf( R.drawable.poland ) );
images.put( "germany", Integer.valueOf( R.drawable.germany ) );
String correctAnswer = "poland";
imageView1.setImageResource( images.get( correctAnswer ).intValue() );
In the res/drawable-mdpi folder I have 26 letter images, named big_0.png to big_25.png.
I would like to add them all (and ignore any other images in the folder) to a hash map:
private static HashMap<Character, Drawable> sHash =
new HashMap<Character, Drawable>();
Initially I was planning something like:
private static final CharacterIterator ABC =
new StringCharacterIterator("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
int i = 0;
for (char c = ABC.first();
c != CharacterIterator.DONE;
c = ABC.next(), i++) {
String fileName = "R.drawable.big_" + i;
Drawable image = context.getResources().getDrawable(fileName);
sHash.put(c, image);
}
But then I've realized that R.drawable.big_0 to R.drawable.big_25 are of type int and not String.
So please advise me, how to iterate through the 26 images correctly?
Use getResources().getIdentifier() to convert "R.drawable.big_" + i into the resource ID value that you would use with getDrawable().
Android version:4.2
I am developing an android App. I need to generate images from drawable folder randomly. In my drawable I have 45 images with different names.
My xml code is:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
I have tried with this code:
ImageView img=(ImageView)findViewById(R.id.imageView1);
Random rand = new Random();
int rndInt = rand.nextInt(52) + 1;
String drawableName = "photo"+ rndInt;
int resID = getResources().getIdentifier(drawableName, "drawable", getPackageName());
img.setImageResource(resID);
But with this code I need to change my image names to photo1, photo2, ... and I don't want to do it.
Any suggestion on how to implement it? Thank you.
One way is to create an array with required image's ids. And take random one from that array. That approach is explained in other answers.
Another way is to create file random_images_array.xml in values folder of your project and fill it like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="apptour">
<item>#drawable/image_1</item>
<item>#drawable/photo_2</item>
<item>#drawable/picture_4</item>
</array>
</resources>
And then you can take random image from that xml array:
final TypedArray imgs = getResources().obtainTypedArray(R.array.random_images_array);
final Random rand = new Random();
final int rndInt = rand.nextInt(imgs.length());
final int resID = imgs.getResourceId(rndInt, 0);
Third method is to take random field from R.drawable class:
final Class drawableClass = R.drawable.class;
final Field[] fields = drawableClass.getFields();
final Random rand = new Random();
int rndInt = rand.nextInt(fields.length);
try {
int resID = fields[rndInt].getInt(drawableClass);
img.setImageResource(resID);
} catch (Exception e) {
e.printStackTrace();
}
How about
long[] res = {R.drawable.image1, R.drawable.image2};
or
int[] res = {R.drawable.image1, R.drawable.image2};
and
int rndInt = rand.nextInt(res .length);
img.setImageDrawable(getResources().getDrawable(res[rndInt]));
Be specific about your question - what do you actually want to do?
if you want to show images in random order than this would be best
int resId[]={R.drawable.p1,R.drawable.p2,R.drawable.p2};
Random rand = new Random();
int index = rand.nextInt((resId.length- 1) - 0 + 1) + 0;
imgView.setImageResource(resId[index]);
If you want the absolute file path of image to rename it, see this article for details.
ImageView img=(ImageView)findViewById(R.id.imageView1);
String[] imageArray = {"Image1", "Image2", etc..};
Random rand = new Random();
int rndInt = rand.nextInt(52) + 1;
int resID = getResources().getIdentifier(imageArray[rand], "drawable", getPackageName());
img.setImageResource(resID);
You have to see this question or answer also:-
Randomize string from resources android
but you have to replace
textview.setText()
to
img.setImageResource(ran.nextInt(trivias.length)]);`
I found that setting an array with all of the drawables and then getting a random index through a random number would work.
public int[] Images = {R.drawable.1, R.drawable.2, R.drawable.3};
And then
ImageView EightBallImage = findViewById(R.id.EightBallImage);
EightBallImage.setImageResource(Images[new Random().nextInt(Images.length)]);
Either inside a click listener or just in the onCreate method
In my project I'm trying to display several image files by manipulating the filename of one of the images programatically.
ie, I may have:
filename.jpg, filename_top.jpg, filename_middle.jpg
I receive input of an drawable int and am trying to find the filename of the displayed image before manipulating this filename and trying to display the programatically generated filenames.. problem is that the manipulated filename does not display.
ie. there is something wrong with this:
imageView2.setImageResource(getImageId(this, namebottom));
Any ideas how getImageId can be modified to make setImageResource work properly?
The code would look something like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bun = getIntent().getExtras();
int imagenumber = bun.getInt("imagenumber");
String extension = bun.getString("extension");
// int become a val from 0 to 20 (array size)
setContentView(R.layout.clickeditem);
final int[] imgIds = new int[{
R.drawable.image0,R.drawable.image1,R.drawable.image2,,,R.drawable.image20};
//The first image with id top in the layout is set ok:
ImageView imageView1 = (ImageView)findViewById(R.id.top);
imageView1.setImageResource(imgIds [ imagenumber ] );
// problem here:
//try to get the name of this file: ie: filename.jpg
// and then manipulate the filename:
String name = imageView1.getResources().getString(R.id.image0);
//try to convert this to the filename_middle.jpg
String namemiddle = name.replace(".jpg", "_middle.jpg");
imageViewt.setImageResource(getImageId(this, namemiddle));
//try to convert this to filename_bottom.jpg
String namebottom = name.replace(".jpg", "_bottom.jpg");
imageView2.setImageResource(getImageId(this, namebottom));
}
//where getImageId is defines as follows:
public static int getImageId(Context context, String imageName)
{
return context.getResources().getIdentifier("drawable/" + imageName,
null, context.getPackageName());
}
return context.getResources().getIdentifier("drawable/" + imageName,
null, context.getPackageName());
replace this by
return context.getResources().getIdentifier(imageName,
"drawable", context.getPackageName());