Tag方法
void setTag(Object tag)
这个方法相对简单,如果只需要设置一个 tag,那么直接调用 setTag(Object tag) 取值:view.getTag();方法就可以轻松搞定
void setTag (int key, Object tag)
“ The specified key should be an id declared in the resources of the application to ensure it is unique (see the ID resource type). Keys identified as belonging to the Android framework or not associated with any package will cause an IllegalArgumentExceptionto be thrown.”
IllegalArgumentException 的原因就在于 key 不唯一,那么如何保证这种唯一性呢?
我使用了private static final int TAG_ONLINE_ID = 1;
用来当做 Key 可是还是会报错。但这是为什么呢?
/**
* Returns the tag associated with this view and the specified key.
*
* @param key The key identifying the tag
*
* @return the Object stored in this view as a tag
*
* @see# setTag(int, Object)
* @see# getTag()
*/
public Object getTag(int key) {
if (mKeyedTags != null) return mKeyedTags.get(key);
return null;
}
/**
* Sets a tag associated with this view and a key. A tag can be used
* to mark a view in its hierarchy and does not have to be unique within
* the hierarchy. Tags can also be used to store data within a view
* without resorting to another data structure.
*
* The specified key should be an id declared in the resources of the
* application to ensure it is unique (see the <a
* href={@docRoot}guide/topics/resources/more-resources.html# Id">ID resource type</a>).
* Keys identified as belonging to
* the Android framework or not associated with any package will cause
* an {@link IllegalArgumentException} to be thrown.
*
* @param key The key identifying the tag
* @param tag An Object to tag the view with
*
* @throws IllegalArgumentException If they specified key is not valid
*
* @see# setTag(Object)
* @see# getTag(int)
*/
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);
}
从源码中可以看到,key右移24位如果小于2就会抛出这个异常,这个应该和id的生成规则有关。
这样来看key也是可以定义成一个常量的(测试了也确实可以),只要保证这个移位大于2的规则就行。但是这样写不便于维护,只是说是可行的,不建议这边做。
从源码中注意到的另外一个问题是,setTag()中的tag是单独存储的,保存在protected Object mTag;中,而setTag(int key, final Object tag)的tags是保存在private SparseArray<Object> mKeyedTags;中的。
那么知道问题就好解决了:
最直接的方法就是在资源文件中添加一条记录:
<item type="id" name="tag_first"></item>
可以添加到res/values/strings.xml或者res/values/ids.xml中,然后调用View.setTag(R.id.tag_first,"msg")即可。
网友评论