How to bind a layout_width and layout_height using

2019-04-07 02:24发布

问题:

I'm trying to bind a boolean that indicates to an ImageView if the screen size is small, so it shrinks if I need more space for other components. I'm using the DataBinding Library to do so.

My layout whose width and height depends on this boolean:

...
<data>
    ...
    <variable name="smallScreen" type="boolean"/>
    ...
</data>
...
<ImageView
android:layout_width="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size}"
android:layout_height="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size}"
android:layout_gravity="center_horizontal"
android:contentDescription="@{message}"
android:src="@{image}"
android:scaleType="center"
tools:src="@drawable/img_message_private"/>
...

If I just try to build my project like this, the compiler says layout_width cannot accept type float. Fair enough, I use the BindingAdapter class to create a float enter for layout attributes, as follows:

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

@BindingAdapter("android:layout_height")
public static void setLayoutHeight(View view, float height) {
    ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
    layoutParams.height = (int) height;
    view.setLayoutParams(layoutParams);
}
...

That allows my project to build. But when the layout is finally being rendered, I fall in the following exception:

java.lang.RuntimeException: Binary XML file line #21: You must supply a layout_width attribute.

Just for information, my dimensions are set in dp units, as follows:

<dimen name="img_small_screen_size">100dp</dimen>
<dimen name="img_big_screen_size">208dp</dimen>

Does someone know how can I override the layout_width attribute so I can use databind with it directly, using dimensions?

回答1:

I just figured it out as I wrote my question. I just used another attribute to bind the one I wanted changed, the code ended like this:

<ImageView
android:layout_width="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size}"
android:layout_height="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size}"
android:layout_gravity="center_horizontal"
android:contentDescription="@{message}"
android:src="@{image}"
android:scaleType="center"
tools:src="@drawable/img_message_private"/>

So my BindingAdapters became this:

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

@BindingAdapter("android:layout_height")
public static void setLayoutHeight(View view, float height) {
    ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
    layoutParams.height = (int) height;
    view.setLayoutParams(layoutParams);
}


回答2:

You should add a default value, i.e.,

android:layout_width="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size, default=wrap_content}"