Android databinding set alignParentTop

2019-04-28 02:12发布

问题:

I have following layout (only relevant parts left):

<RelativeLayout>
    <View android:layout_alignParentTop="true"/>
</RelativeLayout>

I tried setting layout_alignParentTop attribute with variable declared in <data> block as shown here:

<data>
    <variable
        name="condition"
        type="Boolean"/>
</data>

<RelativeLayout>
    <View android:layout_alignParentTop="@{condition}"/>
</RelativeLayout>

However when trying to compile, android studio says the following:

Error: Cannot find the setter for attribute 'android:layout_alignParentTop' with parameter type java.lang.Boolean.

How can I set layout_alignParentTop attribute with databinding variable?

回答1:

I had to do some digging into this and I found a recent issue in Google Code.

To quote one of the project members:

We explicitly did not support data binding for layout properties, though you could technically add them yourself. The problem is that these can be easily abused with people trying to animate them.

To implement these for your application, create a binding adapter:

@BindingAdapter("android:layout_width")
public static void setLayoutWidth(View view, int width) {
  LayoutParams layoutParams = view.getLayoutParams();
  layoutParams.width = width;
  view.setLayoutParams(layoutParams);
}

In your case you would just need to adjust it slightly for the alignParentTop attribute:

@BindingAdapter("android:layout_alignParentTop")
public static void setAlignParentTop(View view, boolean alignParentTop) {
   RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
      RelativeLayout.LayoutParams.WRAP_CONTENT,
      RelativeLayout.LayoutParams.WRAP_CONTENT);

   if(alignParentTop) {
      layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
   }

   view.setLayoutParams(layoutParams);
}

This is untested, but it should be enough to get you on the right track.



回答2:

@BindingAdapter("android:layout_alignParentLeft")
public static void setAlignParentLeft(View view, boolean alignParentLeft) {
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
            view.getLayoutParams()
    );

    if (alignParentLeft) {
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    }

    view.setLayoutParams(layoutParams);
}

this code is more universal and does not apply wrap_content for each view