La chiave deve essere un ID risorsa specifico dell'applicazione


145

Perché ottengo questa eccezione?

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 linea in questione è:

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

e l'ho definito come:

private static final int TAG_ONLINE_ID = 1;

Risposte:


55

L'ID tag deve essere univoco, quindi desidera che sia un ID creato in un file di risorse per garantire l'univocità.

Se la vista conterrà solo un tag, puoi farlo

setTag(objContact.onlineid);

3
ancora non capisco lo schema. voglio impostare due tag corrispondenti a dire un nome e un cognome. dove definisco gli ID interi per questi?
Jeffrey Blattman,

7
Puoi usare qualsiasi risorsa, anche solo prendere un R.id.FOO a caso in cui FOO è un id nel tuo progetto.
Artem Russakovskii,

16
È il modo migliore per ottenere un ID tag univoco? Davvero Android?
jimmy0251,

Ehi, cosa succede se non so quanti tag ci sono? perché voglio generare viste secondo alcuni dati nel modello ....
jsina,

Una possibile soluzione al problema di Asker, ma non è la soluzione migliore. Non dovrebbe essere contrassegnato come risposta ...
angryITguy

226

Il motivo per cui non sei in grado di usare setTag (int, Object) è perché Android richiede un ID univoco precompilato nell'argomento 'int'.

Prova a creare due voci uniche in String.xml xml, pronuncia "firstname" e "secondname" e usale come di seguito

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

129
aggiungi questo al tuo file strings.xml: <item type = "id" name = "TAG_ONLINE_ID" /> e puoi usarlo come una normale risorsa id: R.id.TAG_ONLINE_ID
EtienneSky

9
questa dovrebbe essere la risposta. è più generico.
IronBlossom,

2
@AjithMemana perché? Quando l'app viene compilata, il file strings.xml assegna un ID risorsa int univoco a ciascun elemento. Il valore dell'elemento stringa non viene preso in considerazione.
ataulm,

1
Grazie, è fantastico e utile ... anche se vuoi ottenere il tag devi accedere ai valori delle stringhe come v.getTag (R.string.name)
Amt87

5
Meglio creare un nome file ids.xml nella directory res / valori e aggiungere lì tutti i tuoi ID univoci.
vovahost,

146

Sono un po 'in ritardo alla festa, ma oggi mi sono imbattuto in questo problema e ho pensato di dare una risposta. Questa risposta sarà un po 'una raccolta delle altre risposte, ma con una svolta. Prima di tutto, l'id, come è stato sottolineato da altri, NON può essere una costante definita nel tuo codice (come final statico privato int MYID = 123) o qualsiasi altro int che definisci un campo da qualche parte.

L'id deve essere un ID univoco precompilato, proprio come quelli che ottieni per le stringhe che inserisci in valori / strings.xml (ovvero R.string.mystring). Fare riferimento a http://developer.android.com/guide/topics/resources/available-resources.html e http://developer.android.com/guide/topics/resources/more-resources.html per ulteriori informazioni.

Il mio suggerimento è di creare un nuovo file chiamato valori / tags.xml e scrivere:

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

Penso che sia meglio creare un file separato invece di inserirlo in strings.xml come suggerito da EtienneSky.


14
Puoi anche farcela <item name="TAG_ONLINE_ID" type="id"/>per semplificare.
Benoit Duffez,

Questa è la vera soluzione; Non il newbie "Non capisco quello che sto facendo, ma questo hack funziona" -solution
Roel

nota, per l'accesso in uso di codice R.id..., e non R.string.. oR.tags...
g2server

Questo è stato utile e qui è un altro post in cui mostra il suo utilizzo: stackoverflow.com/questions/28492493/...
prasad_

E assicurati di inserire il file nei valori e non nella cartella xml. :)
Nantoka,

55

Questo farà il lavoro ...

Se hai solo 1 setTag nella tua classe, puoi usare qualsiasi int, magari final static dichiarato in alto.

Il problema si presenta quando hai avuto 2 o più setTag con chiavi diverse. Intendo:

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

Quello scenario è sbagliato. È quindi necessario aggiungere un file di valori chiamato forse ids.xml con il seguente:

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

Quindi, nella tua classe, chiama:

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

migliore spiegazione per i nuovi arrivati
Richard Le Mesurier,

Questa è la vera soluzione: non la correzione hack per principianti!
Roel,

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

dovrebbe funzionare. Maggiori informazioni da ceph3us :

La chiave specificata deve essere un ID dichiarato nelle risorse dell'applicazione per garantire che sia univoco Le chiavi identificate come appartenenti al framework Android o non associate a nessun pacchetto causeranno il lancio di IllegalArgumentException.

dalla fonte:

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

Perché l'ID deve essere uno generato nel tuo file R.java.
StackOverflow

No non lo fa. Deve essere maggiore di 2 << 24, tutto qui.
Anton Duzenko,

Bene, l'approccio 1 + 2 << 24, 2 + 2 << 24 ecc funziona davvero. Sembra una soluzione irregolare. Mi piace sapere perché è così? Ci sono dei rischi, ad esempio nelle future versioni di Android ecc.? È di gran lunga soffocante usarlo definito come costante?
Jan Bergström,

Perché è hardcoded in Android SDK. Non cambierà mai perché altrimenti tutte le app Android esistenti smetteranno di funzionare.
Anton Duzenko,

1
Suppongo che il problema principale in questa soluzione sia che non garantisce l'univocità di questa chiave, il che significa che aggiungendo qualche libreria o altro codice che utilizza la funzione setTag questa logica può rompersi se l'id generato corrisponderà a quello ottenuto da questa soluzione.
EdgarK,

3

Ho usato viewHolder.itemTitleTextView.getId(). Ma puoi anche dichiarare nelle tue risorse: <item type="id" name="conversation_thread_id"/>


0

Questo funziona per me:

setTag(0xffffffff,objContact.onlineid);

0

Il motivo per cui vuoi salvare il valore con un ID è che vuoi coprire più di un valore in questo tag, giusto?
Ecco una soluzione più semplice:
supponiamo che tu voglia salvare due valori (Stringhe) in questo tag: "firstname" e "lastname". Puoi salvarli entrambi in una stringa, separati da punto e virgola:

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

... e accedervi dividendoli in un array di stringhe:

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

0

puoi usare questo:

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

per ID risorsa specifico dell'applicazione uniqness

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.