如何在Android中使用数据绑定来绑定layout_width和layout_height?

9
我想绑定一个布尔值,用于指示ImageView是否应缩小以腾出更多空间给其他组件。我使用DataBinding库来实现此功能。
我的布局的宽度和高度取决于这个布尔值:
...
<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"/>
...

如果我只是像这样尝试构建我的项目,编译器会报错,说layout_width不能接受float类型。很好,我使用BindingAdapter类来为布局属性创建一个浮点数输入,如下所示:

...
@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);
}
...

这使得我的项目可以构建。但当最终呈现布局时,我遇到了以下异常:

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

仅供参考,我的尺寸是以dp单位设置的,具体如下:

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

有人知道我如何覆盖layout_width属性,以便我可以直接使用绑定数据,并使用尺寸吗?

2个回答

8

您应该添加一个默认值,即

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

2
谢谢。设置默认值解决了我的问题。但是我有一个疑问,既然第一个或第二个值将被执行,为什么还需要默认值呢? - Shubham
谢谢!你的帖子也帮助了我! - Sam
1
@Shubham 这完全取决于操作员何时将 "smallScreen" 变量绑定到布局。如果它比第一个布局通行证晚,那么上述错误将被抛出。此外,请记住,如果您不想或不能使用适当的工具属性,那么默认值对于布局预览非常有用。 - ubuntudroid

6

当我写问题时,我想到了解决方法。我只需使用另一个属性来绑定我想要更改的属性,代码最终如下:

<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"/>

那么我的BindingAdapters变成了这样:

@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
你也可以使用“android:layout_width”。你不必使用自己的命名空间。 - George Mount
5
现在你的回答看起来和问题一样了。 - Bolein95

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接