Enlace de datos de Android layout_width y layout_height
Necesito poder establecer dinámicamente una propiedad de altura de EditText. Estoy utilizando la vinculación de datos para otras propiedades en toda mi aplicación, por lo que me encantaría poder utilizar la vinculación de datos para controlar la altura de mis elementos. Aquí está una versión simplificada de mi 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>
Y aquí está una versión reducida de mi View Model:
- Android vinculación de datos (similar a WPF)?
- Vinculación de datos de Android mediante etiqueta de inclusión
- DataBinding con Android Dialog
- Obtener una clase vinculante desde vista
- Android - ¿Cómo enlazar un ListView a una colección de objetos personalizados?
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(); }
Las dimensiones están en el archivo dimens.xml. Y estoy modificando las propiedades en el modelo de vista. Pero, cuando lanzo la aplicación, estoy recibiendo el siguiente error inmediatamente después del lanzamiento (el bindingadapter no está disparando en depuración). Tengo varios otros elementos en la pantalla, pero este particular es el que necesito para cambiar la altura cuando se produce una acción particular:
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.
Hay algunos posts sobre SO con respecto a este tema, pero no hay respuestas definitivas o el enfoque no funcionó. Seguramente esta es una implementación que es común. Gracias de antemano por la ayuda.
- Cómo crear vinculación de datos personalizados en android? (Estudio del androide)
- Android: ¿Variable vinculante y pasando para incluir trabajo de diseño de etiquetas?
- Formato HTML en la nueva biblioteca de enlace de datos de Android
- Cómo pasar ObservableField dentro del control interno
- ¿Cómo usar com.android.databinding en el módulo (estudio de Android)?
- 'No se puede encontrar la variable de símbolo' en la vinculación de datos android incluyen diseño
- La vinculación de datos de Android produce "Carpetas de origen generadas en una ubicación incorrecta"
- Android dataBinding - @BindingAdapter nombre de la aplicación personalizada que se ignora
Cuando se utiliza la vinculación de datos, extraemos los valores del XML. Puede agregar un valor predeterminado que se utilizará cuando se elimine para evitar el problema.
Consulte: http://developer.android.com/tools/data-binding/guide.html (parte inferior de la página).
android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull, default=wrap_content}"
En Java
@BindingAdapter("layout_height") public static void setLayoutHeight(View view, float height) { LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = height; view.setLayoutParams(layoutParams); }
Y en su XML
app:layout_height="@{ viewModel.isBig ? @dimen/dp_20 : @dimen/dp_5 }"
Importar la aplicación como esta
xmlns:app="http://schemas.android.com/apk/res-auto"
Según la discusión sobre el rastreador de problemas de Android, es imposible establecer altura o ancho de diseño con enlace de datos sin crear adaptadores de enlace personalizados:
https://code.google.com/p/android/issues/detail?id=180666
El adaptador de enlace necesario para ajustar la altura de la vista sería así:
@BindingAdapter("android:layout_height") public static void setLayoutHeight(View view, int height) { LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = height; view.setLayoutParams(layoutParams); }
- Android: cómo agregar Icono en el lado izquierdo de la TextView
- FrameLayout no coincide con altura de NestedScrollView