Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

What is the main purpose of such methods as setTag() and getTag() of View type objects?

Am I right in thinking that I can associate any number of objects with a single View?

like image 425
Eugene Avatar asked Mar 13 '11 19:03

Eugene


People also ask

What is setTag and getTag in Android?

The setTag() method takes an argument of type Object , and getTag() returns an Object .

How do you get tags from view in Kotlin?

You need to use the getTag() method that take a key parameter, since you set your tags using keys.


2 Answers

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.

like image 126
Matthew Willis Avatar answered Sep 22 '22 11:09

Matthew Willis


I'd like to add few words.

Although using get/setTag(Object) seems to be very useful in the particular case of a ViewHolder pattern, I'd recommend to think twice before using it in other cases. There is almost always another solution with better design.

The main reason is that code like that becomes unsupportable pretty quickly.

  • It is non-obvious for other developers what you designed to store as tag in the view. The methods setTag/getTag are not descriptive at all.

  • It just stores an Object, which requires to be cast when you want to getTag. You can get unexpected crashes later when you decide to change the type of stored object in the tag.

  • Here's a real-life story: We had a pretty big project with a lot of adapters, async operations with views and so on. One developer decided to set/getTag in his part of code, but another one had already set the tag to this view. In the end, someone couldn't find his own tag and was very confused. It cost us several hours to find the bug.

setTag(int key, Object tag) looks much better, cause you can generate unique keys for every tag (using id resources), but there is a significant restriction for Android < 4.0. From Lint docs:

Prior to Android 4.0, the implementation of View.setTag(int, Object) would store the objects in a static map, where the values were strongly referenced. This means that if the object contains any references pointing back to the context, the context (which points to pretty much everything else) will leak. If you pass a view, the view provides a reference to the context that created it. Similarly, view holders typically contain a view, and cursors are sometimes also associated with views.

like image 39
Andrei Buneyeu Avatar answered Sep 22 '22 11:09

Andrei Buneyeu