2016-02-09 10 views
8

Potrzebuję móc dynamicznie ustawić właściwość height EditText. Używam powiązania danych dla innych właściwości w mojej aplikacji, więc chciałbym móc użyć powiązania danych do kontrolowania wysokości moich elementów. O to okrojona wersja mojego xml:Android Data Binding układ_width i 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> 

I tu jest okrojona wersja mojego widoku modelu:

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

Wymiary są w pliku dimens.xml. I modyfikuję właściwości w modelu widoku. Ale po uruchomieniu aplikacji pojawia się następujący błąd natychmiast po uruchomieniu (bindadapter nie uruchamia debugowania). Mam kilka innych elementów na ekranie, ale to przede wszystkim jeden jest jeden muszę zmienić wysokość, gdy wystąpi określone działanie:

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. 

Istnieje kilka stanowisk na SO dotyczące tego problemu, ale nie ma ostatecznych odpowiedzi lub gdy podejście nie działa. Z pewnością jest to powszechna implementacja. Z góry dziękuję za pomoc.

+1

„Na pewno jest to realizacja, która jest wspólna” - biorąc pod uwagę, że wiązania danych jest nadal kandydatem do wydania, Nie uważam * nic * związanego z wiązaniem danych za "powszechne". Nie zdziwiłbym się, gdyby nie można było ustawić wysokości i szerokości w ten sposób, ponieważ dane te są sprawdzane natychmiast po nadaniu układu, a do tego czasu nie wstrzyknięto jeszcze modelu, nie mówiąc już o ustawieniu tych atrybutów. Możliwe, że istnieje pewne obejście tego problemu, używając właściwości syntetycznej (np. 'App: width'), do której zastosujesz wyrażenie wiążące, które dostosuje widok' LayoutParams'. – CommonsWare

+0

Możesz być absolutnie poprawny. Myślę, że ze względu na moją znajomość powiązań danych na innych platformach (Windows), spodziewałem się, że będzie to również powszechne na Androida. –

Odpowiedz

18

Po powiązaniu danych usuwamy wartości z pliku XML. Możesz dodać wartość domyślną, która będzie używana podczas usuwania, aby uniknąć problemu.

patrz: http://developer.android.com/tools/data-binding/guide.html (dół strony).

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

Nie widziałem tego w żadnym innym wątku SO. Dzięki wielkie! –

+2

To nie zadziałało dla mnie: 'Błąd: (13, 34) Nie można znaleźć ustawiacza dla atrybutu" android: układ_width "z typem parametru float na android.widget.LinearLayout. ' –

+0

@GuilhermeTorresCastro Proszę sprawdzić moją odpowiedź poniżej –

1

Według dyskusji na Androida emisyjnej trackera, nie jest możliwe, aby ustawić wysokość układu lub szerokości z wiązaniem bez tworzenia niestandardowych wiążące adapterów danych:

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

Adapter wiązania potrzebne do ustawienia widoku wysokość będzie wyglądać tak:

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

W Javie

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

I w XML

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

import aplikacja tak

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

To powinna być poprawna odpowiedź – Badjano

+1

dzięki za przypomnienie mi, gotowe! – Badjano

+0

Musiałem dodać domyślną wartość dla Androida: layout_height = "@ {smallScreen? @ Dimen/dp_20: @ dimen/dp_5, default = wrap_content}" – Shubham