What Is the Main Purpose of Settag() Gettag() Methods of View

What is the main purpose of setTag() getTag() methods of View?

Let's say you generate a bunch of views that are similar. You could set an OnClickListener for each view individually:

button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...

Then you have to create a unique onClick method for each view even if they do the similar things, like:

public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}

This is because onClick has only one parameter, a View, and it has to get other information from instance variables or final local variables in enclosing scopes. What we really want is to get information from the views themselves.

Enter getTag/setTag:

button1.setTag(1);
button2.setTag(2);

Now we can use the same OnClickListener for every button:

listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};

It's basically a way for views to have memories.

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

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

What is the working of setTag and getTag in ViewHolder pattern?

tag is a mechanism to make your views remember something, that could be an object an integer a string or anything you like.

so when your ListView is going to create for the first time your convertView is null. so you create a new convertView and put all of your references of the objects of that row in a viewHolder. then save your viewHolder into the memory of that convertView(setTag). Android takes your convertView and puts it in its pool to recycle it and passes it again to you. but its pool may not have enough convertViews so it again passes a new convertView thats null. so again the story is repeated till the pool of android is filled up. after that android takes a convertView from its pool and passes it to you. you will find that its not null so you ask it where are my object references that I gave to you for the first time? (getTag) so you will get those and do whatever you like.

More elaboration on below line

but its pool may not have enough convertViews so it again passes a new convertView thats null

android pool is empty when your listView is going to create. so for the first item of your listView it sends you a convertView that must be displayed. after that android saves it in its pool, so its pool now contains just one convertView. for your second item of your listView that is going to create android can not use its pool because it is actually has one element and that element is your first item and it is being shown right now so it has to pass another convertView. this process repeates until android found a convertView in its pool thats not being displayed now and passes it to you.

Android inflates each row till the screen filled up after that when you scroll the list it uses holder.

What is the use of the View's setTag method?

Basically you can store any kind of object as tag (and cast it back when calling getTag). This can be a simple ID or some complex data. It's some information which you associate with this view.

In the case of lists and the view holder pattern it's a simple object which contains references to views of the tagged view (group). So you don't have to call findViewById every time when you're updating the content of the view. It's just an performance optimization.

Can we store data of list item in the view tag?

No. Because of view recycling you have (e.g.) 10 views which are reused for 1000 list items. Storing data in the tag makes no sense here. It's better to use an custom data object to store the list item state (probably the same array which contains the displayed data) or you persist it right away on list item change.

See also setTag documentation.

Android: How to use View's setTag, getTag and findViewWithTag methods?

This line is part of your culprit:

com.jacksmartie.PhotoMem.MainActivity$1.onItemClick(MainActivity.java:79)

Put a breakpoint here:

Log.d("View 1", imageView.toString());

And look what your imageview reference object [imageView] is, I'm expecting that it is null because you aren't linking it properly.

If it is null, this means that your link to the reference view is not right. If that's the case, then you need to assign it properly like so:

Button b = findViewById(R.id.Button01);

However; since you're using what seems to be a ListView, the pulling of that is slightly different. This means that the way you're pulling the view is wrong, do some research, should find something to help clear that up!

How to use setTag and getTag with custom adapter

your code is little bit confusing, so I give you a sample

Sample Tag class

public class MyTag
{
String code;
String image;
String web_ref;

public MyTag()
{
code=null;
image=null;
web_ref=null;
}

public MyTag(String cod,String img,String wref)
{
code=cod;
image=img;
web_ref=wref;
}

}

you want to get this values when clicked on button right ? So put this tag class object as tag on button in getView of your custom adapter

MyTag myTag=new MyTag("code","image","web_ref");
holder.button.setTag(myTag);

since you get the view clicked as argument to the your function

public void shareOnClickHandler(View v) 
{

myTag=(MyTag)v.getTag();
text=myTag.code;
image2.loadUrl("http://"+myTag.image);//..... I'm not sure, thank you
webview.loadUrl(mytag.web_ref);
}

I think you get the idea, try to implement your code with this idea

Why use getTag/setTag when we can do the same with static variable

But here in my code if I replace this via simple static ViewHolder, it works fine

No, it does not.

First, you are leaking memory like a sieve.

Second, as soon as the user scrolls, your approach will break, as you will start updating the wrong ImageView. Your code is relying upon the fact that rows never get recycled, which will only be true if either your ListView/GridView does not require much scrolling, or if you have a seriously messed-up adapter that is trying to avoid view recycling altogether.



Related Topics



Leave a reply



Submit