【问题标题】:Android:Purpose of getTag() and setTag() in View ClassAndroid:View Class中getTag()和setTag()的用途
【发布时间】:2014-10-21 06:43:18
【问题描述】:
public void setTag(final Object tag) {
                mTag = tag;
}
public Object getTag() {
            return mTag;
}

这是 Android 中 View 类的两个方法。 以下分别是这两种方法的官方文档。

 /**
     * Returns this view's tag.
     *
     * @return the Object stored in this view as a tag
     *
     * @see #setTag(Object)
     * @see #getTag(int)


        */
 /**
     * 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.
     *
     * @param tag an Object to tag the view with
     *
     * @see #getTag()
     * @see #setTag(int, Object)
     */

标签函数在 baseadapter 实现中被广泛使用,但我无法理解它的用途以及如何使用它们。请你解释一下这个很好的例子来帮助我理解这些函数的作用

【问题讨论】:

标签: android android-view


【解决方案1】:

把它想得尽可能简单——一个“标签”。

杂货店产品标签告诉您什么? 基本上很多东西,比如名称、价格、原产国、折扣等等。

假设您正在制作一个使用 ImageView 在网格中显示此类产品的应用程序。 如何从 ImageView 中轻松确定产品特征?标记它是可能的解决方案之一。

class Product {

    String mName;
    String mManufacturer;
    String mOriginCountry;

    double mPrice;
    int mDiscount;

    int mImageId; // A reference to a drawable item id
}

[...]

class My Activity {

    @Override
    protected void onCreate() {
        [...] // Some code

        // Grab the imageView reference and grab (or create) the tag for it
        ImageView someItemView = (ImageView) findViewById(R.id.some_product_view);
        Product someProductTag = new Product( ... some data ...);

        // Add the tag to the ImageView
        someItemView.addTag(someProductTag);
    }

    private void displayItemInfo(ImageView iv) {

        // Grab the tag and display the info.
        String productName = ((Product)iv.getTag()).mName();
        Toast.show(mContext, "This is " + productName, Toast.LONG).show(); 

    }

}

当然,这是非常简化的。理想情况下,您应该有一个适配器,它可以根据您提供的标签创建视图,或者自动创建您的标签。

希望你能理解

【讨论】:

    【解决方案2】:

    View Holder 模式就是一个很好的例子。可以在 ListViews 上的 this tutorial 中找到实现。

    View Holder 模式允许避免适配器中的 findViewById() 方法。

    ViewHolder 类是适配器中的静态内部类,它保存对相关视图的引用。在您的布局中。此引用通过 setTag() 方法作为标记分配给行视图。

    如果我们收到一个 convertView 对象,我们可以通过 getTag() 方法获取 ViewHolder 的实例,并通过 ViewHolder 引用将新属性分配给视图。

    虽然这听起来很复杂,但这比使用 findViewById() 方法快大约 15%。

    例子

    以下代码显示了一个性能优化的适配器实现,它重用现有视图并实现了持有者模式。

    import android.app.Activity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MyPerformanceArrayAdapter extends ArrayAdapter<String> {
      private final Activity context;
      private final String[] names;
    
      static class ViewHolder {
        public TextView text;
        public ImageView image;
      }
    
      public MyPerformanceArrayAdapter(Activity context, String[] names) {
        super(context, R.layout.rowlayout, names);
        this.context = context;
        this.names = names;
      }
    
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        // reuse views
        if (rowView == null) {
          LayoutInflater inflater = context.getLayoutInflater();
          rowView = inflater.inflate(R.layout.rowlayout, null);
          // configure view holder
          ViewHolder viewHolder = new ViewHolder();
          viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
          viewHolder.image = (ImageView) rowView
              .findViewById(R.id.ImageView01);
          rowView.setTag(viewHolder);
        }
    
        // fill data
        ViewHolder holder = (ViewHolder) rowView.getTag();
        String s = names[position];
        holder.text.setText(s);
        if (s.startsWith("Windows7") || s.startsWith("iPhone")
            || s.startsWith("Solaris")) {
          holder.image.setImageResource(R.drawable.no);
        } else {
          holder.image.setImageResource(R.drawable.ok);
        }
    
        return rowView;
      }
    } 
    

    【讨论】:

      【解决方案3】:

      它们只是将Object 附加到视图的一种方式。
      在 BaseAdapter 中,它用于存储视图 id,以避免每次系统请求视图时进行昂贵的findViewById 操作。

      【讨论】:

        【解决方案4】:

        Tag 字段是为任何视图类存储您自己的状态信息的好方法。一种用途是将视图的位置存储在ListView 中。有关示例,请参阅此 answer

        【讨论】:

          【解决方案5】:

          setTag(int, object) 对于将自定义类存储到视图非常有用。这是我的实现:

           itemView.setTag(R.id.food_tag, food);
          

          变量 food 是自定义对象 Food 的一个实例。 setTag 的键应该始终是资源 id。

          我可以通过这种方式在OnClickListener() 中检索这个自定义对象:

          Food selectedFood = (Food) view.getTag(R.id.food_tag);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-15
            • 2014-06-29
            • 2011-07-14
            • 1970-01-01
            相关资源
            最近更新 更多