I'm trying to use databinding with custom views (a possible usage George Mount showed here).
One can't imagine building compound views without <merge>
tag. However, in this situation databinding fails:
MyCompoundView
class:
public class MyCompoundView extends RelativeLayout {
MyCompoundViewBinding binding;
public MyCompoundView (Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
binding = MyCompoundViewBinding.inflate(inflater, this, true);
}
my_compound_view.xml
: by app:isGone="@{!data.isViewVisible}"
i hoped to control the visibility of the whole compound view
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<variable name="data" type="com.example.MyViewModel"/>
</data>
<merge
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:isGone="@{!data.isViewVisible}">
<ImageView
android:id="@+id/image_image"
android:layout_width="60dp"
android:layout_height="60dp"
app:imageUrl="@{data.imagePhotoUrl}"/>
<!-- tons of other views-->
</merge>
</layout>
The compiler errors:
Error:(13) No resource identifier found for attribute 'isGone' in package 'com.example'
Error:(17, 21) No resource type specified (at 'isGone' with value '@{!data.isViewVisible}').
I have all needed @BindingAdapter
methods. Now I inherit the view from FrameLayout
and use <RelativeLayout>
instead of <merge>
- and it works. But I have extra nested layout.
Question: merge
attrs are ignored. Is there any way to workaround that?
Android Studio 1.5.1 stable
Gradle plugin com.android.tools.build:gradle:1.5.0
There is no merge object after inflation, so there is nothing to assign values to with a merge tag. I can't think of any binding tag that will work on merge.
You can assign the tag to the root element and use the BindingAdapter to do what you want.
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<variable name="data" type="com.example.MyViewModel"/>
</data>
<merge
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
app:isGone="@{!data.isViewVisible}"
android:id="@+id/image_image"
android:layout_width="60dp"
android:layout_height="60dp"
app:imageUrl="@{data.imagePhotoUrl}"/>
<!-- tons of other views-->
</merge>
</layout>
If you want to do something with the Binding class itself, you can use the DataBindingUtil to find the object from the View.
@BindingAdapter("isGone")
public static void setGone(View view, boolean isGone) {
ViewDataBinding binding = DataBindingUtil.findBinding(view);
//... do what you want with the binding.
}