Je dois pouvoir définir de manière dynamique la propriété height d'un EditText. J'utilise la liaison de données pour d'autres propriétés dans l'application, alors j'aimerais pouvoir utiliser la liaison de données pour contrôler la hauteur de mes éléments. Voici une version allégée de mon 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>
Et voici une version allégée de mon modèle View:
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();
}
Les dimensions sont dans le fichier dimens.xml. Et je modifie les propriétés dans le modèle de vue. Mais, lorsque je lance l'application, l'erreur suivante apparaît immédiatement après le lancement (bindingadapter ne se déclenche pas lors du débogage). J'ai plusieurs autres éléments à l'écran mais celui-ci est celui dont j'ai besoin pour changer la hauteur lorsqu'une action particulière se produit:
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.
Il y a quelques articles sur SO concernant cette question, mais aucune réponse définitive ou l'approche n'a pas fonctionné. C’est sûrement une implémentation courante. Merci d'avance pour l'aide.
En java
@BindingAdapter("layout_height")
public static void setLayoutHeight(View view, float height) {
LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = height;
view.setLayoutParams(layoutParams);
}
Et dans votre XML
app:layout_height="@{ viewModel.isBig ? @dimen/dp_20 : @dimen/dp_5 }"
importer l'application comme ça
xmlns:app="http://schemas.Android.com/apk/res-auto"
Lorsque la liaison de données est utilisée, nous supprimons les valeurs du XML. Vous pouvez ajouter une valeur par défaut à utiliser lorsqu’elle est supprimée pour éviter le problème.
voir: http://developer.Android.com/tools/data-binding/guide.html (en bas de la page).
Android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull, default=wrap_content}"
Selon la discussion sur Android Issue Tracker, il est impossible de définir la hauteur ou la largeur de la disposition avec la liaison de données sans créer d'adaptateurs de liaison personnalisés:
https://code.google.com/p/Android/issues/detail?id=180666
L'adaptateur de liaison nécessaire pour définir la hauteur de vue ressemblerait à ceci:
@BindingAdapter("Android:layout_height")
public static void setLayoutHeight(View view, int height) {
LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = height;
view.setLayoutParams(layoutParams);
}
Je l'ai résolu comme ça à Kotlin.
Faire un fichier appelé
MyBindings.kt
Et mettre en:
@BindingAdapter("bind:customHeight")
fun setLayoutHeight(view: View, height: Float) {
view.layoutParams = view.layoutParams.apply { this.height = height.toInt() }
}
Et vous pouvez ensuite utiliser cela dans vos mises en page:
<EditText
Android:id="@+id/internalTopDisplay"
Android:layout_width="match_parent"
bind:customHeight="="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull}"
Android:layout_height="wrap_content"/>
Pour moi, c'est le truc:
@BindingAdapter("Android:layout_height")
public static void setLayoutHeight(View view, final Number height) {
final ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = height.intValue();
view.setLayoutParams(layoutParams);
}
Et le xml:
Android:layout_height="@{item.isItemCollapsed ? @dimen/radar_item_first_background_height : item.textMaxLines, default=@dimen/radar_item_first_background_height}"