キーはアプリケーション固有のリソースIDである必要があります


145

なぜこの例外が発生するのですか?

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)

問題の行は次のとおりです。

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

そして私はそれを次のように定義しています:

private static final int TAG_ONLINE_ID = 1;

回答:


55

タグIDは一意である必要があるため、リソースファイルで作成されたIDにして、一意性を保証する必要があります。

ビューにタグが1つしか含まれていない場合でも、

setTag(objContact.onlineid);

3
まだパターンがわかりません。姓と名を言うために対応する2つのタグを設定したいと思います。これらの整数IDはどこで定義しますか?
ジェフリーブラットマン、2011年

7
任意のリソースを使用できます。ランダムなR.id.FOOを取得するだけで、FOOはプロジェクトのIDです。
Artem Russakovskii 2011

16
これが一意のタグIDを取得する最良の方法ですか?本当にAndroid?
jimmy0251 2015年

こんにちは、タグの数がわからない場合はどうなりますか?モデルの一部のデータに基づいてビューを生成したいので... ...
jsina

質問者の問題に対する可能な解決策ですが、最良の解決策ではありません。回答としてマークしないでください...
angryITguy

226

setTag(int、Object)を使用できない理由は、Androidが「int」引数に事前にコンパイルされた一意のIDを必要とするためです。

String.xml xmlに「firstname」と「secondname」という2つの一意のエントリを作成して、以下のように使用してみてください

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

129
これをstrings.xmlファイルに追加します:<item type = "id" name = "TAG_ONLINE_ID" />そして、通常のidリソースのように使用できます:R.id.TAG_ONLINE_ID
EtienneSky

9
これが答えです。より一般的です。
IronBlossom

2
@AjithMemanaなんで?アプリがコンパイルされると、strings.xmlファイルは各要素に一意のintリソースIDを割り当てます。文字列要素の値は考慮されません。
ataulm 2013年

1
ありがとう、それはとても素晴らしくて便利です...また、タグを取得したい場合は、v.getTag(R.string.name)などの文字列値にアクセスする必要があります
Amt87

5
res / valuesディレクトリにファイル名ids.xmlを作成し、そこにすべての一意のIDを追加することをお勧めします。
vovahost 2015

146

私はパーティーに少し遅れましたが、私はこの問題に今日自分でつまずいたので、私も答えを出そうと思いました。この回答は、他の回答を少しまとめたものですが、ひねりを加えています。まず、他の人が指摘したように、IDはコードで定義された定数(private static final int MYID = 123など)またはどこかでフィールドとして定義したその他のintにはできません。

idは、values / strings.xml(つまりR.string.mystring)に入力した文字列に対して取得するIDと同じように、プリコンパイルされた一意のIDである必要があります。詳細については、http://developer.android.com/guide/topics/resources/available-resources.htmlおよびhttp://developer.android.com/guide/topics/resources/more-resources.htmlを参照してください。

私の提案は、values / tags.xmlという新しいファイルを作成し、次のように記述することです。

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

EtienneSkyが提案したように、strings.xmlに配置するのではなく、別のファイルを作成する方が良いと思います。


14
<item name="TAG_ONLINE_ID" type="id"/>単純化することもできます。
Benoit Duffez 2013

これが本当の解決策です。初心者ではない「私は何をしているのかわからないが、このハックは機能する」
Roel

ノート、コード使用中にアクセスするR.id...と、いない R.string..R.tags...
g2server

これは有用であったとここでは、その使用を示した別のポストです:stackoverflow.com/questions/28492493/...
prasad_

また、ファイルをxmlフォルダーではなく値に配置してください。:)
Nantoka

55

これは仕事をします...

クラスにsetTagが1つしかない場合は、任意のintを使用できます。

問題は、異なるキーを持つ2つ以上のsetTagがある場合に発生します。というのは:

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

そのシナリオは間違っています。次に、ids.xmlという名前の値ファイルを次のように追加する必要があります。

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

次に、クラスで次を呼び出します。

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

初心者のための最良の説明
Richard Le Mesurier 2016年

これが本当の解決策です:初心者のハック修正ではありません!
Roel

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

うまくいくはずです。ceph3usの詳細:

指定されたキーは、アプリケーションのリソースで宣言されたIDである必要があります。Androidフレームワークに属している、またはどのパッケージにも関連付けられていないことが識別されると、IllegalArgumentExceptionがスローされます。

ソースから:

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

IDはR.javaファイルで生成されたものでなければならないためです。
StackOverflowed 2013

いいえ、違います。2 << 24より大きい必要があります。それだけです。
Anton Duzenko 2013

まあ、1 + 2 << 24、2 + 2 << 24などのアプローチは実際に機能します。不規則な修正のように見えます。なぜこんな感じなのか知りたい?たとえば、Androidの将来のバージョンなどでリスクはありますか?それを定数として定義して使用することははるかに窒息していますか?
JanBergström、2016

Android SDKにハードコードされているためです。変更しないと、既存のすべてのAndroidアプリが機能しなくなるためです。
Anton Duzenko 2016

1
このソリューションの主な問題は、このキーの一意性が保証されないことです。つまり、setTag機能を使用しているライブラリまたは他のコードを追加することにより、生成されたIDがこのソリューションから取得したものと一致する場合、このロジックは壊れる可能性があります。
EdgarK 2016

3

私は使用しましたviewHolder.itemTitleTextView.getId()。ただし、リソースで宣言することもできます。 <item type="id" name="conversation_thread_id"/>



0

IDで値を保存する理由は、このタグで複数の値をカバーしたいということですよね?
ここでより簡単な解決策:
このタグに「firstname」と「lastname」という2つの値(文字列)を保存するとします。両方をセミコロンで区切って1つの文字列に保存できます。

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

...そして、それらを文字列配列に分割することによってそれらにアクセスします:

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

0

あなたはこれを使うことができます:

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

一意性アプリケーション固有のリソースID

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.