Kuncinya harus berupa id sumber daya khusus aplikasi

145

Mengapa saya mendapatkan Pengecualian ini?

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)

baris yang dimaksud adalah:

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

dan saya mendefinisikannya sebagai:

private static final int TAG_ONLINE_ID = 1;
Pentium10
sumber

Jawaban:

55

Tag id harus unik sehingga ingin menjadi id yang dibuat dalam file sumber daya untuk menjamin keunikan.

Jika tampilan hanya akan berisi satu tag, Anda bisa melakukannya

setTag(objContact.onlineid);
Robby Pond
sumber
3
saya masih belum mendapatkan polanya. saya ingin menetapkan dua tag yang sesuai untuk mengucapkan nama depan dan belakang. di mana saya mendefinisikan ID integer untuk ini?
Jeffrey Blattman
7
Anda dapat menggunakan sumber daya apa pun - bahkan hanya mengambil R.id.FOO acak di mana FOO adalah id dalam proyek Anda.
Artem Russakovskii
16
Itu cara terbaik untuk mendapatkan tag id unik? Sungguh Android?
jimmy0251
Hai, bagaimana jika saya tidak tahu berapa banyak tag? karena saya ingin menghasilkan tampilan sesuai dengan beberapa data dalam model ....
jsina
Solusi yang mungkin untuk masalah penanya, tetapi bukan solusi terbaik. Seharusnya tidak ditandai sebagai jawabannya ...
angryITguy
226

Alasan Anda tidak dapat menggunakan setTag (int, Object) adalah karena android memerlukan id unik yang dikompilasi sebelumnya dalam argumen 'int'.

Coba buat dua entri unik di String.xml xml katakan, "firstname" & "secondname" & gunakan seperti di bawah ini

imageView.setTag(R.string.firstname, "Abhishek");
imageView.setTag(R.string.lastname, "Gondalia");
ABDroids
sumber
129
tambahkan ini ke file strings.xml Anda: <item type = "id" name = "TAG_ONLINE_ID" /> dan Anda dapat menggunakan seperti sumber id biasa: R.id.TAG_ONLINE_ID
EtienneSky
9
yang ini harus menjadi jawabannya. ini lebih umum.
IronBlossom
2
@AjithMemana mengapa? Ketika aplikasi dikompilasi, file strings.xml memberikan id sumber daya int unik untuk setiap elemen. Nilai elemen string tidak diperhitungkan.
ataulm
1
Terima kasih, itu sangat hebat dan bermanfaat ... juga jika Anda ingin mendapatkan tag, Anda perlu mengakses nilai string seperti v.getTag (R.string.name)
Amt87
5
Lebih baik buat nama file ids.xml di direktori res / values dan tambahkan semua id unik Anda di sana.
vovahost
146

Saya agak terlambat ke pesta, tetapi saya sendiri tersandung masalah ini hari ini dan berpikir saya akan memberikan jawaban juga. Jawaban ini akan sedikit kompilasi dari jawaban yang lain, tetapi dengan twist. Pertama-tama, id, seperti yang telah ditunjukkan oleh orang lain, TIDAK dapat berupa konstanta yang didefinisikan dalam kode Anda (seperti MYID int final statis swasta = 123) atau int lain yang Anda tetapkan sebagai bidang di suatu tempat.

Id harus berupa id unik yang dikompilasi, sama seperti id yang Anda dapatkan untuk string yang Anda masukkan ke nilai / strings.xml (yaitu R.string.mystring). Lihatlah http://developer.android.com/guide/topics/resources/available-resources.html dan http://developer.android.com/guide/topics/resources/more-resources.html untuk informasi lebih lanjut.

Saran saya adalah Anda membuat file baru bernama values ​​/ tags.xml dan menulis:

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

Saya pikir lebih baik membuat file terpisah daripada meletakkannya di strings.xml seperti yang disarankan EtienneSky.

britzl
sumber
14
Anda bahkan dapat membuatnya <item name="TAG_ONLINE_ID" type="id"/>untuk menyederhanakan.
Benoit Duffez
Ini adalah solusi nyata; Bukan newbie "Saya tidak mengerti apa yang saya lakukan tetapi hack ini berhasil" -solusi
Roel
perhatikan, untuk mengakses dalam penggunaan kode R.id..., dan bukan R.string.. atauR.tags...
g2server
Ini berguna dan berikut ini adalah pos lain yang menunjukkan penggunaannya: stackoverflow.com/questions/28492493/…
prasad_
Dan pastikan Anda meletakkan file dalam nilai-nilai dan bukan di folder xml. :)
Nantoka
55

INI AKAN MELAKUKAN PEKERJAAN ...

Jika Anda hanya memiliki 1 setTag di kelas Anda, Anda bisa menggunakan int, mungkin final statis yang dideklarasikan di atas.

Masalahnya muncul ketika Anda memiliki 2 setTag atau lebih dengan kunci yang berbeda. Maksudku:

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

Skenario itu salah. Anda kemudian perlu menambahkan file nilai yang disebut mungkin ids.xml dengan yang berikut:

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

Kemudian, di kelas Anda, hubungi:

 ...
 setTag(R.id.resourceDrawable, KEY_1)
 setTag(R.id.imageURI, KEY_2)
 ...
Sterling Diaz
sumber
Penjelasan terbaik untuk pendatang baru
Richard Le Mesurier
Ini adalah solusi nyata: bukan perbaikan hack pemula!
Roel
8
private static final int TAG_ONLINE_ID = 1 + 2 << 24;

harus bekerja. Info lebih lanjut dari ceph3us :

Kunci yang ditentukan harus merupakan id yang dideklarasikan di sumber daya aplikasi untuk memastikan itu adalah Kunci unik yang diidentifikasi sebagai milik kerangka Android atau tidak terkait dengan paket apa pun akan menyebabkan IllegalArgumentException dilempar.

dari sumber:

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);
}
Anton Duzenko
sumber
Karena ID harus salah satu yang dihasilkan dalam file R.java Anda.
StackOverflowed
Tidak. Itu harus lebih besar dari 2 << 24, itu saja.
Anton Duzenko
Ya, pendekatan 1 + 2 << 24, 2 + 2 << 24 dll benar-benar berfungsi. Sepertinya perbaikan tidak teratur. Saya ingin tahu mengapa seperti ini? Apakah ada risiko, misalnya dalam versi Android dll yang akan datang? Sejauh ini lebih baik untuk menggunakannya didefinisikan sebagai konstanta?
Jan Bergström
Karena hardcoded di Android SDK. Itu tidak akan berubah karena jika tidak semua aplikasi android yang ada akan berhenti berfungsi.
Anton Duzenko
1
Saya kira masalah utama dalam solusi ini adalah tidak menjamin keunikan kunci ini, yang berarti bahwa dengan menambahkan beberapa pustaka atau kode lain yang menggunakan fitur setTag, logika ini dapat pecah jika id yang dihasilkan akan cocok dengan yang didapat dari solusi ini.
EdgarK
3

Saya sudah menggunakan viewHolder.itemTitleTextView.getId(). Tetapi Anda juga dapat mendeklarasikan dalam sumber daya Anda: <item type="id" name="conversation_thread_id"/>

ViliusK
sumber
0

Ini bekerja untuk saya:

setTag(0xffffffff,objContact.onlineid);
kamu xiaofei
sumber
0

Alasan mengapa Anda ingin menyimpan nilai dengan id adalah, bahwa Anda ingin mencakup lebih dari satu nilai dalam tag ini, bukan?
Di sini solusi yang lebih sederhana:
Katakanlah Anda ingin menyimpan dua nilai (Strings) ke dalam tag ini: "firstname" dan "lastname". Anda dapat menyimpan keduanya dalam satu string, dipisahkan dengan titik koma:

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

... dan mengaksesnya dengan membaginya menjadi string array:

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

Anda bisa menggunakan ini:

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

untuk uniqness id sumber daya khusus aplikasi

Jackie Cheng
sumber