2016-02-09 19 views
8

Tôi cần có khả năng tự động đặt thuộc tính chiều cao của EditText. Tôi đang sử dụng ràng buộc dữ liệu cho các thuộc tính khác trong ứng dụng của mình, vì vậy tôi rất muốn có thể sử dụng ràng buộc dữ liệu để kiểm soát chiều cao của các phần tử của tôi. Đây là một phiên bản rút gọn xml của tôi:Bố cục dữ liệu Android layout_width và 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> 

Và đây là một phiên bản rút gọn Xem các mẫu của tôi:

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

Các kích thước là trong file dimens.xml. Và tôi đang sửa đổi các thuộc tính trong mô hình khung nhìn. Tuy nhiên, khi tôi khởi chạy ứng dụng, tôi nhận được lỗi sau ngay lập tức sau khi khởi chạy (bindingadapter không kích hoạt trên debug). Tôi có một số yếu tố khác trên màn hình nhưng có một đặc biệt này là một trong những tôi cần phải thay đổi chiều cao khi một hành động cụ thể xảy ra:

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. 

Có một vài bài viết trên SO về vấn đề này nhưng không có câu trả lời dứt khoát hoặc cách tiếp cận không hoạt động. Chắc chắn đây là một triển khai phổ biến. Xin được cảm ơn trước về sự giúp đỡ.

+1

"Chắc chắn đây là một thực hiện đó là phổ biến" - xem xét rằng dữ liệu ràng buộc vẫn là một ứng cử viên phát hành, Tôi sẽ không xem xét * bất cứ điều gì * liên quan đến dữ liệu ràng buộc là "phổ biến". Tôi sẽ không ngạc nhiên nếu bạn không thể thiết lập chiều cao và chiều rộng theo cách này, vì dữ liệu đó được xác nhận ngay lập tức khi tăng bố cục, và đến thời điểm đó bạn sẽ không tiêm mô hình, hãy để một mình thiết lập các thuộc tính đó. Có thể có một số giải pháp thay thế, sử dụng thuộc tính tổng hợp (ví dụ: 'app: width') mà bạn áp dụng biểu thức ràng buộc của mình, điều chỉnh' LayoutParams' của chế độ xem của bạn. – CommonsWare

+0

Bạn có thể hoàn toàn chính xác. Tôi đoán vì sự quen thuộc của tôi với dữ liệu ràng buộc trên các nền tảng khác (Windows), tôi chỉ mong đợi nó sẽ được phổ biến trên Android là tốt. –

Trả lời

18

Khi liên kết dữ liệu được sử dụng, chúng tôi tách các giá trị khỏi XML. Bạn có thể thêm giá trị mặc định được sử dụng khi nó bị tước để tránh sự cố.

xem: http://developer.android.com/tools/data-binding/guide.html (cuối trang).

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

Tôi không thấy điều này trên bất kỳ chủ đề SO nào khác. Cám ơn rất nhiều! –

+2

Nó không làm việc cho tôi: 'Lỗi: (13, 34) Không thể tìm thấy setter cho thuộc tính 'android: layout_width' với kiểu tham số float trên android.widget.LinearLayout. ' –

+0

@GuilhermeTorresCastro vui lòng kiểm tra câu trả lời của tôi bên dưới –

1

Theo các cuộc thảo luận trên Android theo dõi vấn đề, nó là không thể để thiết lập chiều cao bố trí hoặc chiều rộng với dữ liệu ràng buộc mà không cần tạo adapter tùy chỉnh ràng buộc:

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

Adapter ràng buộc cần thiết để cài đặt xem chiều cao sẽ trông như thế:

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

Trong Java

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

Và trong XML của bạn

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

nhập khẩu các ứng dụng như thế này

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

Đây phải là câu trả lời đúng – Badjano

+1

cảm ơn vì đã nhắc tôi, đã hoàn tất! – Badjano

+0

Tôi phải thêm giá trị mặc định cho nó để hoạt động android: layout_height = "@ {smallScreen? @ Dimen/dp_20: @ dimen/dp_5, mặc định = wrap_content}" – Shubham

Các vấn đề liên quan