2016-02-09 14 views
8

Devo essere in grado di impostare dinamicamente la proprietà height di EditText. Sto utilizzando l'associazione dati per altre proprietà in tutta la mia app, quindi mi piacerebbe poter utilizzare l'associazione dati per controllare l'altezza dei miei elementi. Qui è una versione ridotta del mio xml:Associazione dati Android layout_width e layout_height

<?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> 

E qui è una versione ridotta del mio punto di vista del modello:

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(); 
} 

Le dimensioni sono nel file dimens.xml. E sto modificando le proprietà nel modello di vista. Ma quando lancio l'app, ricevo il seguente errore subito dopo l'avvio (il bindingadapter non viene attivato sul debug). Ho diversi altri elementi sullo schermo, ma questo particolare è quello che ho bisogno di cambiare l'altezza quando si verifica una particolare azione:

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. 

Ci sono alcuni messaggi su SO riguardo a questo problema ma nessuna risposta definitiva o della l'approccio non ha funzionato. Sicuramente questa è un'implementazione comune. Grazie in anticipo per l'aiuto.

+1

"Sicuramente questa è un'implementazione che è comune" - se si considera che l'associazione di dati è ancora una release candidate, Non considererei "qualsiasi cosa * relativo al binding dei dati" comune ". Non sarei sorpreso se non fosse possibile impostare l'altezza e la larghezza in questo modo, dato che i dati vengono convalidati immediatamente dopo aver gonfiato il layout e, a quel punto, non si sarà ancora iniettato il modello, per non parlare di questi attributi. È possibile che ci sia qualche soluzione alternativa, utilizzando una proprietà sintetica (ad es. 'App: width') a cui si applica l'espressione di associazione, che regola i' LayoutParams' della vista. – CommonsWare

+0

Potresti essere assolutamente corretto. Credo che, a causa della mia familiarità con l'associazione dei dati su altre piattaforme (Windows), mi aspettavo solo che fosse comune anche su Android. –

risposta

18

Quando si utilizza il collegamento dati, si eliminano i valori dall'XML. È possibile aggiungere un valore predefinito da utilizzare quando viene rimosso per evitare il problema.

vedere: http://developer.android.com/tools/data-binding/guide.html (parte inferiore della pagina).

android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull, default=wrap_content}" 
+0

Non l'ho visto su nessun altro thread SO. Grazie mille! –

+2

Non ha funzionato per me: 'Errore: (13, 34) Impossibile trovare il setter per l'attributo 'android: layout_width' con il tipo di parametro float su android.widget.LinearLayout. ' –

+0

@GuilhermeTorresCastro si prega di controllare la mia risposta sotto –

1

Secondo la discussione su Android issue tracker, è impossibile impostare l'altezza layout o la larghezza di associazione dati senza creare adattatori personalizzati vincolanti:

https://code.google.com/p/android/issues/detail?id=180666

L'adattatore vincolante necessaria per l'impostazione vista altezza apparirebbe così:

@BindingAdapter("android:layout_height") 
public static void setLayoutHeight(View view, int height) { 
    LayoutParams layoutParams = view.getLayoutParams(); 
    layoutParams.height = height; 
    view.setLayoutParams(layoutParams); 
} 
8

In Java

@BindingAdapter("layout_height") 
public static void setLayoutHeight(View view, float height) { 
    LayoutParams layoutParams = view.getLayoutParams(); 
    layoutParams.height = height; 
    view.setLayoutParams(layoutParams); 
} 

E nel tuo XML

app:layout_height="@{ viewModel.isBig ? @dimen/dp_20 : @dimen/dp_5 }" 

importazione app come questo

xmlns:app="http://schemas.android.com/apk/res-auto" 
+1

Questa dovrebbe essere la risposta corretta – Badjano

+1

grazie per avermelo ricordato, fatto! – Badjano

+0

Ho dovuto aggiungere un valore predefinito per funzionare android: layout_height = "@ {smallScreen? @ Dimen/dp_20: @ dimen/dp_5, default = wrap_content}" – Shubham

Problemi correlati