La clave debe ser un ID de recurso específico de la aplicación


145

¿Por qué obtengo esta excepción?

05-18 20:29:38.044: ERROR/AndroidRuntime(5453): java.lang.IllegalArgumentException: The key must be an application-specific resource id.
05-18 20:29:38.044: ERROR/AndroidRuntime(5453):     at android.view.View.setTag(View.java:7704)
05-18 20:29:38.044: ERROR/AndroidRuntime(5453):     at com.mypkg.viewP.inflateRow(viewP.java:518)

La línea en cuestión es:

((Button) row.findViewById(R.id.btnPickContact)).setTag(TAG_ONLINE_ID,objContact.onlineid);

y lo tengo definido como:

private static final int TAG_ONLINE_ID = 1;

Respuestas:


55

La identificación de la etiqueta debe ser única, por lo que quiere que sea una identificación creada en un archivo de recursos para garantizar la unicidad.

Si la vista solo contendrá una etiqueta, solo puede hacer

setTag(objContact.onlineid);

3
Todavía no entiendo el patrón. Quiero establecer dos etiquetas correspondientes para decir un nombre y apellido. ¿Dónde defino los ID enteros para estos?
Jeffrey Blattman

77
Puede usar cualquier recurso, incluso tomar un R.id.FOO aleatorio donde FOO es una identificación en su proyecto.
Artem Russakovskii

16
¿Esa es la mejor manera de obtener una identificación de etiqueta única? ¿De verdad Android?
jimmy0251

Hola, ¿y si no sé cuántas etiquetas hay? porque quiero generar puntos de vista de acuerdo a algunos datos en el modelo ....
jsina

Una posible solución al problema del autor de la pregunta, pero no es la mejor solución. No debe marcarse como la respuesta ...
angryITguy

226

La razón por la que no puede usar setTag (int, Object) es porque Android requiere una identificación única precompilada en el argumento 'int'.

Intente crear dos entradas únicas en String.xml xml, diga "nombre" y "segundo nombre" y utilícelas como se muestra a continuación

imageView.setTag(R.string.firstname, "Abhishek");
imageView.setTag(R.string.lastname, "Gondalia");

129129
agregue esto a su archivo strings.xml: <item type = "id" name = "TAG_ONLINE_ID" /> y puede usarlo como un recurso de identificación normal: R.id.TAG_ONLINE_ID
EtienneSky

9
Esta debería ser la respuesta. Es más genérico.
IronBlossom

2
@AjithMemana ¿por qué? Cuando se compila la aplicación, el archivo strings.xml asigna una identificación de recurso int única a cada elemento. El valor del elemento de cadena no se tiene en cuenta.
ataulm

1
Gracias, eso es genial y útil ... también si desea obtener la etiqueta que necesita para acceder a valores de cadenas como v.getTag (R.string.name)
Amt87

55
Mejor cree un nombre de archivo ids.xml en el directorio res / values y agregue allí todos sus identificadores únicos.
vovahost

146

Llego un poco tarde a la fiesta, pero hoy me topé con este problema y pensé que también daría una respuesta. Esta respuesta será una compilación de las otras respuestas, pero con un giro. En primer lugar, la identificación, como lo han señalado otros, NO puede ser una constante definida en su código (como int privado estático final MYID = 123) o cualquier otra int que defina como un campo en alguna parte.

La identificación debe ser una identificación única precompilada, al igual que las que obtiene para las cadenas que coloca en valores / strings.xml (es decir, R.string.mystring). Consulte http://developer.android.com/guide/topics/resources/available-resources.html y http://developer.android.com/guide/topics/resources/more-resources.html para obtener más información.

Mi sugerencia es que cree un nuevo archivo llamado values ​​/ tags.xml y escriba:

    <resources xmlns:android="http://schemas.android.com/apk/res/android">
      <item name="TAG_ONLINE_ID" type="id"/>
    </resources>

Creo que es mejor crear un archivo separado en lugar de ponerlo en strings.xml como EtienneSky sugirió.


14
Incluso puedes hacerlo <item name="TAG_ONLINE_ID" type="id"/>para simplificar.
Benoit Duffez

Esta es la verdadera solución; No es el novato "No entiendo lo que estoy haciendo, pero este truco funciona" -solución
Roel

nota, para acceder en el uso del código R.id..., y no R.string.. oR.tags...
g2server

Esto fue útil y aquí hay otra publicación donde muestra su uso: stackoverflow.com/questions/28492493/…
prasad_

Y asegúrese de colocar el archivo en los valores y no en la carpeta xml. :)
Nantoka

55

ESTO HARÁ EL TRABAJO ...

Si solo tiene 1 setTag en su clase, puede usar cualquier int, tal vez estático final declarado en la parte superior.

El problema surge cuando tenías 2 o más setTag's con diferentes claves. Quiero decir:

public static final int KEY_1 = 1;
public static final int KEY_2 = 2;
...
setTag(KEY_1)
setTag(KEY_2)
...

Ese escenario está mal. Luego debe agregar un archivo de valor llamado quizás ids.xml con lo siguiente:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="id" name="resourceDrawable" />
    <item type="id" name="imageURI" />
</resources>

Luego, en tu clase, llama al:

 ...
 setTag(R.id.resourceDrawable, KEY_1)
 setTag(R.id.imageURI, KEY_2)
 ...

mejor explicación para los recién llegados
Richard Le Mesurier

Esta es la solución real: ¡no la solución para hackear a los novatos!
Roel

8
private static final int TAG_ONLINE_ID = 1 + 2 << 24;

Deberia trabajar. Más información de ceph3us :

La clave especificada debe ser una identificación declarada en los recursos de la aplicación para garantizar que sea única. Las claves identificadas como pertenecientes al marco de Android o no asociadas a ningún paquete provocarán una IllegalArgumentException.

de fuente:

public void setTag(int key, final Object tag) {
    // If the package id is 0x00 or 0x01, it's either an undefined package
    // or a framework id
    if ((key >>> 24) < 2) {
        throw new IllegalArgumentException("The key must be an application-specific "
                + "resource id.");
    }

    setKeyedTag(key, tag);
}

Porque la ID debe ser una generada en su archivo R.java.
StackOverflowed

No, no lo hace. Tiene que ser mayor que 2 << 24, eso es todo.
Anton Duzenko

Bueno, el enfoque 1 + 2 << 24, 2 + 2 << 24 etc. realmente funciona. Parece una solución irregular. Me gusta saber por qué es así. ¿Hay algún riesgo, por ejemplo, en futuras versiones de Android, etc.? ¿Es mucho más sofocante usarlo definido como una constante?
Jan Bergström

Porque está codificado en Android SDK. Nunca cambiará porque, de lo contrario, todas las aplicaciones de Android existentes dejarán de funcionar.
Anton Duzenko

1
Supongo que el principal problema en esta solución es que no garantiza la uniformidad de esta clave, lo que significa que al agregar alguna biblioteca u otro código que esté usando la función setTag, esta lógica puede romperse si la identificación generada coincidirá con la obtenida de esta solución.
EdgarK

3

He usado viewHolder.itemTitleTextView.getId(). Pero también puedes declarar en tus recursos: <item type="id" name="conversation_thread_id"/>



0

La razón por la que desea guardar el valor mediante una identificación es que desea cubrir más de un valor en esta etiqueta, ¿verdad?
Aquí una solución más simple:
supongamos que desea guardar dos valores (cadenas) en esta etiqueta: "nombre" y "apellido". Puede guardarlos en una cadena, separados por punto y coma:

v.setTag(firstname + ";" + lastname);

... y acceder a ellos dividiéndolos en una matriz de cadenas:

String[] data = v.getTag().toString().split(";");
System.out.println(data[0]) //firstname
System.out.println(data[1]) //lastname

0

puedes usar esto:

private static final int TAG_ONLINE_ID = View.generateViewId() + 2 << 24;

para uniqness id. de recurso específico de la aplicación

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.