Get the ID of a drawable in ImageView
Solution 1
I think if I understand correctly this is what you are doing.
ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
ImageView imageView = (ImageView) view;
assert(R.id.someImage == imageView.getId());
switch(getDrawableId(imageView)) {
case R.drawable.foo:
imageView.setDrawableResource(R.drawable.bar);
break;
case R.drawable.bar:
default:
imageView.setDrawableResource(R.drawable.foo);
break;
}
});
Right? So that function getDrawableId()
doesn't exist. You can't get a the id that a drawable was instantiated from because the id is just a reference to the location of data on the device on how to construct a drawable. Once the drawable is constructed it doesn't have a way to get back the resourceId that was used to create it. But you could make it work something like this using tags
ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
ImageView imageView = (ImageView) view;
assert(R.id.someImage == imageView.getId());
// See here
Integer integer = (Integer) imageView.getTag();
integer = integer == null ? 0 : integer;
switch(integer) {
case R.drawable.foo:
imageView.setDrawableResource(R.drawable.bar);
imageView.setTag(R.drawable.bar);
break;
case R.drawable.bar:
default:
imageView.setDrawableResource(R.drawable.foo);
imageView.setTag(R.drawable.foo);
break;
}
});
Solution 2
I answered something like this in another question already, but will change it just a little for this one.
Unfortunately, there is no getImageResource()
or getDrawableId()
. But, I created a simple workaround by using the ImageView tags.
In onCreate():
imageView0 = (ImageView) findViewById(R.id.imageView0);
imageView1 = (ImageView) findViewById(R.id.imageView1);
imageView2 = (ImageView) findViewById(R.id.imageView2);
imageView0.setTag(R.drawable.apple);
imageView1.setTag(R.drawable.banana);
imageView2.setTag(R.drawable.cereal);
Then, if you like, you can create a simple function to get the drawable id:
private int getDrawableId(ImageView iv) {
return (Integer) iv.getTag();
}
Too easy.
Solution 3
As of today, there is no support on this function. However, I found a little hack on this one.
imageView.setImageResource(R.drawable.ic_star_black_48dp);
imageView.setTag(R.drawable.ic_star_black_48dp);
So if you want to get the ID of the view, just get it's tag.
if (imageView.getTag() != null) {
int resourceID = (int) imageView.getTag();
//
// drawable id.
//
}
Solution 4
A simple solution might be to just store the drawable id in a temporary variable. I'm not sure how practical this would be for your situation but it's definitely a quick fix.
Solution 5
Digging StackOverflow for answers on the similar issue I found people usually suggesting 2 approaches:
- Load a drawable into memory and compare ConstantState or bitmap itself to other one.
- Set a tag with drawable id into a view and compare tags when you need that.
Personally, I like the second approach for performance reason but tagging bunch of views with appropriate tags is painful and time consuming. This could be very frustrating in a big project. In my case I need to write a lot of Espresso tests which require comparing TextView
drawables, ImageView
resources, View
background and foreground. A lot of work.
So I eventually came up with a solution to delegate a 'dirty' work to the custom inflater. In every inflated view I search for a specific attributes and and set a tag to the view with a resource id if any is found. This approach is pretty much the same guys from Calligraphy used. I wrote a simple library for that: TagView
If you use it, you can retrieve any of predefined tags, containing drawable resource id that was set in xml layout file:
TagViewUtils.getTag(view, ViewTag.IMAGEVIEW_SRC.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_LEFT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_TOP.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_RIGHT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_BOTTOM.id)
TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id)
TagViewUtils.getTag(view, ViewTag.VIEW_FOREGROUND.id)
The library supports any attribute, actually. You can add them manually, just look into the Custom attributes section on Github. If you set a drawable in runtime you can use convenient library methods:
setImageViewResource(ImageView view, int id)
In this case tagging is done for you internally. If you use Kotlin you can write a handy extensions to call view itself. Something like this:
fun ImageView.setImageResourceWithTag(@DrawableRes int id) {
TagViewUtils.setImageViewResource(this, id)
}
You can find additional info in Tagging in runtime
chikka.anddev
Updated on March 22, 2020Comments
-
chikka.anddev about 4 years
I have one
ImageView
and set a drawable on it. Now I need to get the ID of the drawable on click event ofImageView
dynamically. How can I get it?imgtopcolor = (ImageView) findViewById(R.id.topcolor); imgtopcolor.setImageResource(R.drawable.dr); // How do I get this back?
Now on touch event of
imgtopcolor
i want to need drawable id because I am setting different drawable each time and want to compare the drawable with other -
chikka.anddev over 13 yearsThanks for reply.but i think there is no such method like getDrawableID().
-
chikka.anddev over 13 yearsya sure but i have to than convert the tag object into integer to get tag.and my job is done
-
Greg Giacovelli over 13 yearscool srry I didn't have a compiler for that one. Just make sure to try to use Integer.valueOf() instead of doing new Integer(). It just creates more waste if you use new for integers that should be recycled. Hopefully less than 256.
-
Cote Mounyo over 10 yearsWhat do I set in tag in xml file? do I do
android:tag="@drawable/foo"
-
Greg Giacovelli over 10 yearsIf you are statically defining it in xml, at that point you might as well just use the imageView id. As far as I know setting a tag in xml only sets the tag to a string.
-
Ruchir Baronia over 8 yearsCan you set the tags to regular drawable image objects?
-
Anonsage over 8 yearsThe tag can be set to any
Object
. -
Kikiwa about 8 yearsBad idea, the view ids are used for other things and you shuold not do that, never. Ex: you set a random id to a view and then you want to access the view ... how can you identify it since you've lost the previous layout id? :/
-
ADM over 7 yearsYou can set the Draawable Id as tag on view if you wanna save it for later
-
Ultimo_m almost 6 yearsor using content description could be a possible solution if you dont use it for testing purposes
-
Greg Giacovelli almost 6 years@Ultimo_m I would only advise against that because that is not only for testing purposes but for accessibility. A screen reader would use this to describe the image to a visually impaired user of your app. You should always fill that field out with meaningful content describing the representation of the image.
-
Ultimo_m almost 6 yearsYou're right :). That's something developers should pay attention to