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?
View binding doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files. View binding doesn't support two-way data binding.
In Android, the Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
Stay organized with collections Save and categorize content based on your preferences. The @={} notation, which importantly includes the "=" sign, receives data changes to the property and listen to user updates at the same time.
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}"
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With