Search code examples
androiddata-bindingnamespacesandroid-databinding

Namespaces in binding adapter?


I am trying android data-binding and I am really amazed with its capabilities. It really shifts all the getters and setters of views to a single place (layout files or custom binding adapters) .

But, I don't understand what is the use of the namespace here? I was reading a recent article from George on Medium here, and he mentioned that:

Anything in the application namespace doesn’t need any namespace in the parameter, but for attributes in the android namespace, you must give the full attribute name including the “android.”

So, if I don't give a namespace, it works. My custom attributes are namespaced with xmlns:app="http://schemas.android.com/apk/res-auto" . I really don't know what that means.

Say I have a text view where I am doing this like this (hardcoded strings just for example) :

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text='@{"Created By:" + user.name + " on " + user.time}' />

It's really good as I can provide arguments here:

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:createdBy="@{user.name}"
        app:createdAt="@{user.time}" />

And handling that code in Java by setting that text to the same as on above example. This provides an easy to use and understandable code for the layout files.

But, this arguments can collide sometimes. If I am using this at 2 different places with 2 different formats like Created by User A on 7/10/2016 and From User A (7/10/2016). This both can requires same arguments as I showed in second example. How can I distinguish them?

I can also provide third argument like app:format and so that my custom binding function can understand, but can namespaces play the important role here? Can I provide a custom namespaces for multiple data-binding elements and handle them accordingly in my binding adapters? Or namespaces will just be ignored as George mentioned in his article?

In the official documentation they have used bind: namespace and in binding adapter methods they have provided namespace there. I am little bit confused about namespaces' role in data-binding.


Solution

  • XML is very flexible and allows you to provide any number of namespaces. Android, however, isn't (yet) flexible enough to handle more than two -- android and your application's namespace. Android data binding doesn't distinguish between any application namespace name. e.g. bind: or app: doesn't matter because they all refer to http://schemas.android.com/apk/res-auto.

    So, the answer to your question is "No." Namespaces won't really help. You could use the android namespace -- assuming there aren't unfortunate collisions. That only extends your flexibility from one to two and I'm pretty sure you want something better than that.

    This specific example is perfect for string formatting expressions:

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text='@{@string/createdBy(user.name, user.time)}' />
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text='@{@string/fromUser(user.name, user.time)}' />
    

    But generally speaking, you'll have to either use different attributes names for different uses or add an attribute for the differentiator as you suggested.