Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

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

like image 414
LearningBasics Avatar asked Aug 27 '14 15:08

LearningBasics


3 Answers

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.

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 very simplified. 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

like image 88
Jitsu Avatar answered Oct 17 '22 04:10

Jitsu


A good example is the View Holder pattern. An implementation can be found in this tutorial on 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.

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;
  }
} 
like image 29
MrEngineer13 Avatar answered Oct 17 '22 05:10

MrEngineer13


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

like image 2
Simon Marquis Avatar answered Oct 17 '22 06:10

Simon Marquis