Как связать layout_width и layout_height с помощью привязки данных в Android

Я пытаюсь связать логическое значение, которое указывает на ImageView, если размер экрана мал, поэтому он сжимается, если мне нужно больше места для других компонентов. Я использую библиотеку привязки данных для выполнения так.

Мой макет, ширина и высота которого зависят от этого логического значения:

...
<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, чтобы я мог напрямую использовать с ним привязку данных, используя размеры?


person Felipe Jun    schedule 18.01.2016    source источник


Ответы (2)


Вы должны добавить значение по умолчанию, т.е.

android:layout_width="@{smallScreen ? @dimen/img_small_screen_size : @dimen/img_big_screen_size, default=wrap_content}"
person qichuan    schedule 20.12.2016
comment
Спасибо. установка значения по умолчанию решает мою проблему. Но у меня есть одно сомнение, значение по умолчанию никогда не будет выполнено, будет работать либо первое, либо второе значение, тогда почему значение по умолчанию? - person Shubham; 13.06.2017
comment
Спасибо! Ваш пост мне тоже помог! - person Sam; 06.08.2017
comment
@Shubham все зависит от того, когда оператор фактически привязывает переменную smallScreen к макету. Если это произойдет позже первого прохода макета, будет выдана вышеупомянутая ошибка. Кроме того, имейте в виду, что значение по умолчанию может оказаться очень удобным для предварительного просмотра макета, если вы не хотите или можете использовать соответствующий атрибут инструментов. - person ubuntudroid; 06.06.2019

Я только что понял это, когда писал свой вопрос. Я просто использовал другой атрибут, чтобы связать тот, который я хотел изменить, код закончился так:

<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);
}
person Felipe Jun    schedule 18.01.2016
comment
Вы также можете использовать android:layout_width. Вам не нужно использовать собственное пространство имен. - person George Mount; 20.01.2016
comment
Теперь ваш ответ выглядит так же, как вопрос - person Bolein95; 28.01.2016