Мне нужно иметь возможность динамически устанавливать свойство высоты EditText. Я использую привязку данных для других свойств в моем приложении, поэтому я хотел бы иметь возможность использовать привязку данных для управления высотой моих элементов. Вот урезанная версия моего xml:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="loginVM" type="com.testing.stuff.ViewModels.LoginViewModel" /> </data> <EditText android:inputType="number" android:id="@+id/txtVerificationCode" android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull}" android:layout_width="match_parent" android:paddingRight="16dp" android:paddingLeft="16dp" android:focusable="true" android:focusableInTouchMode="true" android:layout_marginLeft="10dp" android:alpha="@{loginVM.verificationOpacity}" android:layout_marginStart="10dp" android:textAlignment="center" android:visibility="visible" android:hint="Enter verificationCode" android:text="@{loginVM.verificationCode}" /> </layout>
И вот урезанная версия моей модели просмотра:
public class LoginViewModel extends BaseObservable { public final ObservableField<String> verificationCode; public final ObservableField<Boolean> compact; @Bindable public String getVerificationCode() { if (this.verificationCode == null) { return ""; } else { return this.verificationCode.get(); } } public void setVerificationCode(String verificationCode) { this.verificationCode.set(verificationCode); invalidateProperties(); } @Bindable public Boolean getCompact(){return this.compact.get();} public void setCompact(Boolean value) { this.compact.set(value); this.invalidateProperties(); } @BindingAdapter("android:layout_height") public static void setLayoutHeight(EditText view, float height) { ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = (int)height; view.setLayoutParams(layoutParams); } public LoginViewModel(Context ctx) { verificationCode = new ObservableField(); compact = new ObservableField(); }
Размеры находятся в файле dimens.xml. И я изменяю свойства в модели представления. Но когда я запускаю приложение, я получаю следующую ошибку сразу после запуска (привязка не срабатывает при отладке). У меня есть несколько других элементов на экране, но именно этот вопрос мне нужен, чтобы изменить высоту, когда происходит конкретное действие:
FATAL EXCEPTION: main Process: com.testing.stuff, PID: 32752 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.testing.stuff/com.testing.stuff.Login}: java.lang.RuntimeException: Binary XML file line #69: You must supply a layout_height attribute. Caused by: java.lang.RuntimeException: Binary XML file line #69: You must supply a layout_height attribute.
Есть несколько сообщений по этому вопросу, но никаких окончательных ответов или подхода не получилось. Конечно, это обычная реализация. Заранее спасибо за помощь.
Когда используется привязка данных, мы удаляем значения из XML. Вы можете добавить значение по умолчанию, которое будет использоваться, когда оно будет удалено, чтобы избежать проблемы.
См. http://developer.android.com/tools/data-binding/guide.html (внизу страницы).
android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull, default=wrap_content}"
В Java
@BindingAdapter("layout_height") public static void setLayoutHeight(View view, float height) { LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = height; view.setLayoutParams(layoutParams); }
И в вашем XML
app:layout_height="@{ viewModel.isBig ? @dimen/dp_20 : @dimen/dp_5 }"
Импортируйте приложение, подобное этому
xmlns:app="http://schemas.android.com/apk/res-auto"
Согласно обсуждению трекера Android, невозможно установить высоту или ширину макета с привязкой данных без создания настраиваемых адаптеров привязки:
https://code.google.com/p/android/issues/detail?id=180666
Адаптер привязки, необходимый для установки высоты представления, будет выглядеть так:
@BindingAdapter("android:layout_height") public static void setLayoutHeight(View view, int height) { LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = height; view.setLayoutParams(layoutParams); }