147

为什么我会得到这个异常?

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;
4

10 回答 10

231

您无法使用 setTag(int, Object) 的原因是 android 在 'int' 参数中需要预编译的唯一 ID。

尝试在 String.xml xml 中创建两个唯一条目,例如“firstname”和“secondname”并按如下方式使用它们

imageView.setTag(R.string.firstname, "Abhishek");
imageView.setTag(R.string.lastname, "Gondalia");
于 2011-05-30T16:46:21.207 回答
155

我参加聚会有点晚了,但我今天自己偶然发现了这个问题,并认为我也会给出答案。这个答案将是其他答案的汇编,但有所不同。首先,正如其他人所指出的,id 不能是您的代码中定义的常量(例如 private static final int MYID = 123)或您在某处定义为字段的任何其他 int。

id 必须是预编译的唯一 id,就像您为放入 values/strings.xml(即 R.string.mystring)中的字符串获得的那些。有关详细信息,请参阅http://developer.android.com/guide/topics/resources/available-resources.htmlhttp://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 中。

于 2013-02-22T10:16:44.763 回答
59

这将完成这项工作......

如果你的类中只有 1 个 setTag,你可以使用任何 int,也许是在顶部声明的 static final。

当您有 2 个或更多具有不同键的 setTag 时,问题就出现了。我是说:

public static final int KEY_1 = 1;
public static final int KEY_2 = 2;
...
setTag(KEY_1, VALUE_1)
setTag(KEY_2, VALUE_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, VALUE_1)
 setTag(R.id.imageURI, VALUE_2)
 ...
于 2015-06-14T20:43:30.037 回答
55

标签 id 必须是唯一的,因此它希望它是在资源文件中创建的 id 以保证唯一性。

如果视图将只包含一个标签,但你可以这样做

setTag(objContact.onlineid);
于 2010-05-18T17:48:42.787 回答
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);
}
于 2013-05-02T18:25:41.637 回答
3

我用过viewHolder.itemTitleTextView.getId()。但是你也可以在你的资源中声明: <item type="id" name="conversation_thread_id"/>

于 2014-12-10T10:38:43.543 回答
1

你可以使用这个:

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

用于 uniqness 特定于应用程序的资源 id

于 2020-05-26T01:59:25.060 回答
0

这是一个对我有用的简单解决方法:

int tagKey = "YourSimpleKey".hashCode();

myView.setTag(tagKey, "MyTagObject");

这里的重要线索是调用.hashCode();字符串

于 2020-08-29T20:25:48.270 回答
0

这对我有用:

setTag(0xffffffff,objContact.onlineid);
于 2016-05-08T08:33:33.257 回答
0

您想通过 id 保存值的原因是,您想在此标记中覆盖多个值,对吗?
这里有一个更简单
的解决方案:假设您想将两个值(字符串)保存到这个标签中:“firstname”和“lastname”。您可以将它们保存在一个字符串中,用分号分隔:

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

...并通过将它们拆分为字符串数组来访问它们:

String[] data = v.getTag().toString().split(";");
System.out.println(data[0]) //firstname
System.out.println(data[1]) //lastname
于 2016-05-14T08:05:35.983 回答