避免在 Android 中将视图设置为 setTag 的值

Posted

技术标签:

【中文标题】避免在 Android 中将视图设置为 setTag 的值【英文标题】:Avoid setting views as values for setTag in Android 【发布时间】:2014-09-10 13:01:19 【问题描述】:

我有一个ListView 和一些图像作为列表项。单击任何列表项时,我需要更改该特定列表项的ImageView 的图像源。

我通过将ImageView 作为标签设置为convertView 并随后通过标签获取ImageView 并更改它的来源,成功实现了这一点。

我已将标签设置为,

convertView.setTag(convertView.hashCode(), viewHolder.myImage);

但现在它给了我一个警告,"Avoid setting views as values for setTag: Can lead to memory leaks in versions older than android 4.0".

那么如何避免这种情况呢?或者有什么更好的替代解决方案?

谢谢!

【问题讨论】:

【参考方案1】:

使用View.setTag(Object)方法设置ViewHolder。 和 onClick(View) 使用View.getTag() 获取ViewHolder 并访问您想要更改图像的ImageView

...
convertView.setTag(viewHolder);
...

@Override
public void onClick(View v) 
   ViewHolder holder = (ViewHolder)v.getTag();
   holder.image1.setImage(...);

【讨论】:

是的,这确实有效!但它不会因为我们将更多数据存储为标签而影响性能吗? 不,标签不保存数据,而是保存对象的引用。实际上使用 setTag(key,object) 会占用更多空间,因为您将它们保存在 SparseArray @JafarKhQ 使用 setTag() 设置数据是否有任何限制? @AshishTiwari View.setTag() 将替换为此视图定位的任何先前对象。对象有多大并不重要,它只是为它保存一个引用。 好的。我得到了它。谢谢@JafarKhQ。 :)【参考方案2】:

我也遇到了同样的问题,就这样解决了。

所以,这对 SDK

一种解决方案是返回使用 ViewHolder 模式(您可能已经听说过)加上数据对象的附加字段。普通的 View#setTag(Object) 方法并不邪恶,因为它将数据存储为普通的非静态成员 mTag。

在此处查看更多信息:http://developer.sinnerschrader-mobile.com/handling-android-lint-warning-potential-leak-when-using-settag/399/

private static final class ViewHolder 
    ImageView imageView;
    TextView textView;
    // ...
    Object data;

@Override
public void bindView(View view, Context context, Cursor cursor) 
    ViewHolder holder = (ViewHolder)view.getTag();
    if (holder == null) 
        holder = new ViewHolder();
        holder.imageView = view.findViewById(R.id.icon));
        holder.textView = view.findViewById(R.id.text));
        // ...
    
    holder.imageView.setImageBitmap(someImage);
    holder.textView.setText(someText);
    //...
    holder.data = someData;

【讨论】:

以上是关于避免在 Android 中将视图设置为 setTag 的值的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中将状态栏填充设置为 NavigationView

如何在 android 的 setContentView 中将自定义布局设置为主视图

如何在 Android Studio 中将文本设置为对应的图像

Android XML:在 XML 布局文件中将资源 ID 设置为 View 的标签

当我在故事板中将顶部约束设置为 0 时,如何避免 20 边距?

Android列表视图setOnItemClickListener不起作用