Android:视图类中getTag()和setTag()的用途

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25531253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:32:17  来源:igfitidea点击:

Android:Purpose of getTag() and setTag() in View Class

androidandroid-view

提问by LearningBasics

public void setTag(final Object tag) {
                mTag = tag;
}
public Object getTag() {
            return mTag;
}

These are two methods from View Class in Android. Following is the official documentation of these two methods respectively.

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

 /**
     * 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)
     */

tag functions are used extensively in baseadapter implementation but I couldn't understand its purpose and how to use them. Can you please explain this some good example to help me understand the role of these functions

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

回答by Jitsu

Think of it as as plainly simple as it's possible - a "tag".

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

What does a grocery shop product tag tell you? Basically a lot of things, such as name, price, origin country, discount, and many others.

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

Imagine you're making an application that displays such products in a grid using ImageView's. How to easily determine the product features from the ImageView? Tagging it is one of the possible solutions.

想象一下,您正在制作一个使用 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(); 

    }

}

Of course this is verysimplified. Ideally you would have an adapter which would create the view basing on your provided tags, or would create your tags automatically.

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

I hope you get the idea

我希望你明白

回答by MrEngineer13

A good example is the View Holder pattern. An implementation can be found in this tutorialon ListViews.

一个很好的例子是视图持有者模式。可以在 ListViews 的本教程中找到一个实现。

The View Holder pattern allows to avoid the findViewById() method in the adapter.

A ViewHolder class is a static inner class in your adapter which holds references to the relevant views. in your layout. This reference is assigned to the row view as a tag via the setTag() method.

If we receive a convertView object, we can get the instance of the ViewHolder via the getTag() method and assign the new attributes to the views via the ViewHolder reference.

While this sounds complex this is approximately 15 % faster then using the findViewById() method.

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

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

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

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

The example

这个例子

The following code shows a performance optimized adapter implementation which reuses existing views and implements the holder pattern.

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

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;
  }
} 

回答by Simon Marquis

They are just a way to attach an Objectto the View.
In BaseAdapter, it is used to store view ids to avoid the expensive findViewByIdoperation each time the system request a view.

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

回答by hfann

The Tag field is a good way to store your own state information for any view class. One use is to store the position of a view in a ListView. See this answerfor an example.

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

回答by suku

setTag(int, object)is very useful for storing a custom class to a view. Here is my implementation :

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

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

The variable food is an instance of custom object Food. The key for setTag should always be a resource id.

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

I could retrieve this Custom object this way in the OnClickListener():

我可以通过以下方式检索这个 Custom 对象OnClickListener()

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