避免在 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 的标签