Obtenga la ID de un dibujante en ImageView

Tengo una ImageView y establecí un dibujable sobre ella. Ahora necesito obtener el ID del evento drawable on click de ImageView dinámicamente. ¿Cómo puedo obtenerlo?

 imgtopcolor = (ImageView) findViewById(R.id.topcolor); imgtopcolor.setImageResource(R.drawable.dr); // How do I get this back? 

Ahora, en el evento táctil de imgtopcolor quiero necesitar una ID imgtopcolor porque estoy configurando diferentes dibujables cada vez y quiero comparar el dibujable con el otro

Creo que si entiendo correctamente esto es lo que estás haciendo.

 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; } }); 

¿Derecha? Entonces esa función getDrawableId() no existe. No se puede obtener una ID de la que se creó una instancia de Drawable porque la identificación es solo una referencia a la ubicación de los datos en el dispositivo sobre cómo construir un dibujante. Una vez que se construye el dibujante, no tiene forma de recuperar el Id. De recurso que se usó para crearlo. Pero podrías hacer que funcione algo como esto usando 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; } }); 

Ya respondí algo así en otra pregunta, pero lo cambiaré un poco por esta.

Desafortunadamente, no hay getImageResource() o getDrawableId() . Pero, creé una solución simple mediante el uso de las tags ImageView.

En 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); 

Luego, si lo desea, puede crear una función simple para obtener la ID dibujable:

 private int getDrawableId(ImageView iv) { return (Integer) iv.getTag(); } 

Demasiado fácil.

A partir de hoy, no hay soporte en esta función. Sin embargo, encontré un pequeño truco en este caso.

  imageView.setImageResource(R.drawable.ic_star_black_48dp); imageView.setTag(R.drawable.ic_star_black_48dp); 

Entonces, si quiere obtener el ID de la vista, simplemente obtenga su etiqueta.

 if (imageView.getTag() != null) { int resourceID = (int) imageView.getTag(); // // drawable id. // } 

Una solución simple podría ser simplemente almacenar el ID dibujable en una variable temporal. No estoy seguro de lo práctico que sería para su situación, pero definitivamente es una solución rápida.

Excavar StackOverflow para obtener respuestas sobre un problema similar Encontré personas que suelen sugerir 2 enfoques:

  • Cargue un drawable en la memoria y compare ConstantState o bitmap sí mismo a otro.
  • Establezca una etiqueta con id dibujable en una vista y compare tags cuando lo necesite.

Personalmente, me gusta el segundo enfoque por razones de rendimiento, pero etiquetar un montón de vistas con las tags adecuadas es doloroso y lleva mucho tiempo. Esto podría ser muy frustrante en un gran proyecto. En mi caso, tengo que escribir muchas pruebas de Espresso que requieren comparar los elementos TextView , los recursos de ImageView , View fondo y primer plano. Un montón de trabajo.

Así que finalmente se me ocurrió una solución para delegar un trabajo “sucio” al inflador personalizado. En cada vista inflada, busco atributos específicos y establezco una etiqueta para la vista con una identificación de recursos si se encuentra alguna. Este enfoque es más o menos el mismo tipo de caligrafía utilizada. Escribí una biblioteca simple para eso: TagView

Si lo usa, puede recuperar cualquiera de las tags predefinidas que contengan el ID de recurso dibujable que se configuró en el archivo de diseño xml:

 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) 

La biblioteca admite cualquier atributo, en realidad. Puede agregarlos manualmente, solo mire en la sección de atributos personalizados en Github. Si establece un drawable en tiempo de ejecución, puede usar métodos de biblioteca convenientes:

 setImageViewResource(ImageView view, int id) 

En este caso, el etiquetado se realiza internamente. Si usa Kotlin, puede escribir extensiones útiles para llamar a view. Algo como esto:

 fun ImageView.setImageResourceWithTag(@DrawableRes int id) { TagViewUtils.setImageViewResource(this, id) } 

Puede encontrar información adicional en Etiquetado en tiempo de ejecución

Aún más fácil: simplemente almacene el identificador R.drawable en la identificación de la vista: use v.setId() . Luego vuelve con v.getId() .