View.setTag()和View.getTag()使用指南

关于View.setTag()和View.getTag()结合使用的例子很多,Google, stackoverflow上面一堆,就不再赘述了,随便一搜就有。
经典的使用例子:
三部分:视图初始化、保存内容、取得内容

private ImageView mThumbIv;
mThumbIv = (ImageView) itemView.findViewById(R.id.image);
//使用tag存放View对应在适配器数据集中的位置参数
if (null == mThumbIv) return;
mThumbIv.setTag(position);
//从tag中取出位置参数
int position = (int) v.getTag();

重点来了:View的tag最经典的例子是用来保存在适配器数据集中的位置参数,也是使用最多的场景,那么跟数据适配器配合使用时最好只用来保存位置参数。
为什么这么说呢?
1. 先看tag的作用:

public Object getTag() 
public void setTag(final Object tag)

我们看到,tag 保存的是Object 对象(意味是可以保存同View有关的任何数据,只要你想), 那么你不仅仅可以保存int position, 你还可以保存同该View相关的高度、宽度,甚至创建一个实体类,里面包括各种同View有关的信息。原作者也是这样建议的(来自setTag()函数的注释):

     * Sets the tag associated with this view. 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.

2. tag使用起来的局限性:
当你使用tag的时候,用来保存的内容越多,也就意味着能够影响修改tag的地方越多。尤其是在数据适配器的getView()、onBindViewHolder()等在各种情况下有可能被回调到的方法中使用时,你需要照顾到复杂的、多种有可能调用到setTag()从而造成所保存数据丢失、变更的情况,这毫无疑问增加了你编程的难度和出错的风险。
这也就意味着tag有可能处于一种“不安全”的状态,换句话说你不能确保在每次调用getTag()取得tag数据时确保tag的唯一正确。

因此,在同数据适配器结合使用时,应该只用来保存位置参数,因为只有这样setTag() 同 getTag() 才能一一对应。
而在别的使用场景使用tag时,应该确保tag的稳定性,即setTag() 和 getTag()能够一一对应,使用setTag()对保存数据进行变更时不会对所对应的getTag()造成影响。

你可能感兴趣的:(View.setTag()和View.getTag()使用指南)