Shared publicly  - 
 
Introducing a new <tag /> XML tag to attach info to Android Views

It is no secret, the Android framework has a very open, large and verbose API. It basically lets developers create everything they want as long as they have a clear idea of the final product. However, there are some cases where framework capabilities are not obvious because they are not well documented or just hidden in the verbose API. This is especially true when dealing with the Android View ecosystem. In this post I would like to discuss about how to attach information to a View.

The framework comes with several ways allowing developers to attach information to a View. Some of them have always been available while some other are relatively new. In order to better list these techniques, I have split the post in several parts. Each part relates to an API level.

Android 1.0

Being a object oriented programming language, Java has always offered an easy way to add information to an object: inheritance. The language lets developers prevent this by either making the constructor private or the class final. But because Views have been designed for inheritance, it is quite simple to extend a given class and add information. For instance, you can add information to a TextView creating a TextViewWithData which extends TextView.

Inheritance works great but has one main problem : it is not global. If you want to be able to add info to all View classes, you have to extend all of them creating a "shallow" copy of the framework classes.

Actually, Android has always allowed developers to attach/retrieve information at the View level. This is done thanks to the setTag(Object)[0] and getTag()[1] methods. Android also provides a android:tag[2] XML attribute you can use directly attach a String tag to a given View. In general, you should use findViewById(int) in order to retrieve a given View in a View hierarchy. However, there are some cases where getting a View with a particular tag can be handy. This can be done using findViewWithTag(Object)[3].

Android 1.6

API 4 introduced a new way to attach tag objects to Views. Indeed, both setTag(int, Object)[4] and a _getTag(int)[5] were introduced. The main advantage of these methods was it was possible to add several tags to a View. There are some requirements though: keys had to be a resource identifier (i.e.@+id/something). In practice, these methods were introduced to store references to child Views.

Although these methods methods looked nice it was strongly discourage to use them because the implementation was mostly leading to memory leaks. Indeed, tags were actually held in a static global pool. You can have a look at [6] and [7], and more specifically +Adam Powell comment, to better understand the issue.

Android 4.0

The internal implementation of setTag(int, Object) finally changed in Android 4.0. A switch to a non static SparseArray local to the View itself was made. In other words, starting API 14, it is now safe to use setTag(int, Object) to store references to child Views in the hierarchy.

Android 5.0

Recently, API 21 introduced a brand new way to attach information to Views straight from the XML definition of a layout. A new XML tag <tag /> were in introduced in LayoutInflater allowing us from attaching text information to the parent View. If you like deep diving into the Android source code, you can have a look at +Alan Viverette's commit[8]. Here is an example of how to use it:

values/ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item format="reference" name="btn_state" type="id" />
</resources>

activity_tag.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/btn_negative"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@android:string/cancel">

        <tag
            android:id="@id/btn_state"
            android:value="@string/btn_state_negative"/>

    </Button>

    <Button
        android:id="@+id/btn_positive"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@android:string/ok">

        <tag
            android:id="@id/btn_state"
            android:value="@string/btn_state_positive"/>

    </Button>

</LinearLayout>

The new <tag /> tag brings a new way to statically attach information to a View. It's now up to you to determine some great use cases to this new LayoutInflater-interpreted XML tag.

[0]: http://developer.android.com/reference/android/view/View.html#setTag(java.lang.Object)
[1]: http://developer.android.com/reference/android/view/View.html#getTag()
[2]: http://developer.android.com/reference/android/view/View.html#attr_android:tag
[3]: http://developer.android.com/reference/android/view/View.html#findViewWithTag(java.lang.Object)
[4]: http://developer.android.com/reference/android/view/View.html#setTag(int, java.lang.Object)
[5]: http://developer.android.com/reference/android/view/View.html#getTag(int)
[6]: https://code.google.com/p/android/issues/detail?id=18273
[7]: https://plus.google.com/u/0/+NicolasKlein/posts/2cH1tw3bCy9
[8]: https://github.com/android/platform_frameworks_base/commit/451a3417e97d9d3bb835290a65f9af30b112c789
225
141
Santhyago Gallão's profile photoDanish Aziz's profile photoDamir Mailybayev's profile photopatrice smith's profile photo
11 comments
 
+Cyril Mottier Thanks for sharing! Minor need to rewrite here: "... you can use to set directly attach a String tag ..."
 
Wow. Great information. Is there a way to make this work on API levels below 21? Because otherwise, it is great but not that useful :(
 
+Said Tahsin Dane​ if you want to implement custom elements in layouts, you can also set a custom LayoutInflater.Factory on the LayoutInflater you normally use. This is how the v4 support library implemented the <fragment> tag.
Translate
 
+Cyril Mottier  What do you think which one is good tool for android development 1) Android Studio or 2)eclipse  ?? can you suggest me ?
Add a comment...