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.