Android data binding does not work with View property 'android: tag'

Trying to use the new Android data binding in my project, but I get an error when trying to set the "android: tag" property for some custom variable.

My menu_item.xml file:

<?xml version="1.0" encoding="utf-8"?> <layout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="menuItem" type="com.example.MenuItem" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:tag="@{menuItem}" tools:ignore="UseCompoundDrawables"> <!--suppress AndroidUnknownAttribute --> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:imageResource="@{menuItem.itemType.drawableId}" /> <TextView android:id="@+id/displayName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{menuItem.itemType.displayNameId}" /> </LinearLayout> </layout> 

My MenuItem class:

 public class MenuItem { public final ItemType itemType; public MenuItem(ItemType itemType) { this.itemType = itemType; } } 

Part of the genetic MenyItemBinding.java:

 public MenuItemBinding(View root) { super(root, 0); final Object[] bindings = mapBindings(root, 3, sIncludes, sViewsWithIds); this.displayName = (android.widget.TextView) bindings[2]; this.displayName.setTag(null); this.icon = (android.widget.ImageView) bindings[1]; this.icon.setTag(null); this.mboundView0 = (android.widget.LinearLayout) bindings[0]; this.mboundView0.setTag(root.getResources().getString( com.myApp.R.string.@ {menuItem})); setRootTag(root); invalidateAll(); } 

And an error occurs in the generated class when trying to set the tag of the associated view.

Any ideas how to get around this? It is preferable not to use a custom LinearLayout to support this.

+6
source share
1 answer

This is mistake. We have not tried data binding tags, mainly because the tags are special.

When using pre-ICS device targeting, Android data binding takes on the tag of the outermost layout element. This tag is mainly used for lifecycle bindings and is used by DataBindingUtil.findBinding() and DataBindingUtil.getBinding() .

So, since data binding does not work with tags, the only workaround is to not provide a tag for your LinearLayout or supply a fixed tag or resource string. If you are targeting ICS or later, you can reassign the tag after the layout is bound:

 MenuItemBinding binding = MenuItemBinding.inflate(layoutInflater); binding.getRoot().setTag(menuItem); 

You can also create a BindingAdapter for the new attribute:

 @BindingAdapter("specialTag") public static void setSpecialTag(View view, Object value) { view.setTag(value); } 

and then use it in your layout:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" app:specialTag="@{menuItem}" tools:ignore="UseCompoundDrawables"/> 

This will allow you to use findViewByTag() and all the other things you expect.

However, this will not work if you aim at Honeycomb devices and earlier. This is not enough. You may be tempted to do something like this:

 @BindingAdapter("specialTag") public static void setSpecialTag(View view, Object value) { view.setTag(R.id.app_tag, value); } 

You cannot use findViewByTag with this approach, but it will save any value you want when using your view. But the reason we don’t use ID'd tags with Honeycomb before is because there is a memory leak when using ID'd tags, so don’t do this.

Hope this helps. I will log an error internally to support data-bound android: tags.

+11
source

All Articles