【问题标题】:Avoid setting views as values for setTag in Android避免在 Android 中将视图设置为 setTag 的值
【发布时间】: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".

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

谢谢!

【问题讨论】:

    标签: android android-listview android-imageview


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多