2010-04-13 22 views
81

Tôi không thể ghi đè thuộc tính khi sử dụng < bao gồm > trong tệp bố cục Android của tôi. Khi tôi tìm kiếm lỗi, tôi tìm thấy chối Issue 2863:Thẻ 'Bao gồm' của Android XML Layout có thực sự hoạt động không?

"bao gồm thẻ bị phá vỡ (trọng params bố trí không bao giờ làm việc)"

Kể từ khi Romain chỉ làm việc này trong phòng thí nghiệm và các ví dụ của mình, tôi phải làm gì đó sai rồi.

Dự án của tôi được tổ chức như thế này:

res/layout 
    buttons.xml 

res/layout-land 
    receipt.xml 

res/layout-port 
    receipt.xml 

Các buttons.xml chứa một cái gì đó như thế này:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <Button .../> 

    <Button .../> 
</LinearLayout> 

Và bức chân dung và phong cảnh file receipt.xml giống như thế:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 

    ... 

    <!-- Overridden attributes never work. Nor do attributes like 
     the red background, which is specified here. --> 
    <include 
     android:id="@+id/buttons_override" 
     android:background="#ff0000" 
     android:layout_width="fill_parent" 
     layout="@layout/buttons"/> 

</LinearLayout> 

Tôi đang thiếu gì?

Trả lời

129

Tôi vừa phát hiện sự cố. Trước tiên, bạn chỉ có thể ghi đè thuộc tính layout_ *, vì vậy nền sẽ không hoạt động. Đó là hành vi được ghi lại và chỉ đơn giản là một sự giám sát về phía tôi.

Vấn đề thực sự được tìm thấy trong LayoutInflater.java:

// We try to load the layout params set in the <include /> tag. If 
// they don't exist, we will rely on the layout params set in the 
// included XML file. 
// During a layoutparams generation, a runtime exception is thrown 
// if either layout_width or layout_height is missing. We catch 
// this exception and set localParams accordingly: true means we 
// successfully loaded layout params from the <include /> tag, 
// false means we need to rely on the included layout params. 
ViewGroup.LayoutParams params = null; 
try { 
    params = group.generateLayoutParams(attrs); 
} catch (RuntimeException e) { 
    params = group.generateLayoutParams(childAttrs); 
} finally { 
    if (params != null) { 
    view.setLayoutParams(params); 
    } 
} 

Nếu < bao gồm > thẻ không bao gồm cả layout_width và layout_height, các RuntimeException xảy ra và đang âm thầm xử lý, mà không cần bất kỳ tuyên bố log thậm chí .

Giải pháp là luôn bao gồm cả layout_width và layout_height khi sử dụng < bao gồm thẻ >, nếu bạn muốn ghi đè bất kỳ thuộc tính layout_ * nào.

Ví dụ của tôi sẽ thay đổi thành:

<include 
     android:id="@+id/buttons_override" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     layout="@layout/buttons"/> 
+33

Đây là lố bịch. Tôi chưa bao giờ có thể làm điều này để làm việc, và tôi thậm chí còn thấy tài liệu đề cập đến cần cả chiều cao và chiều rộng nếu cố gắng ghi đè kích thước, mà tôi giả định là chiều cao và chiều rộng. Tuy nhiên, tất cả những gì tôi đã cố gắng để ghi đè là lề, mà không thực sự là một chiều. Tại sao heck tôi cần phải xác định cả hai hoặc thậm chí bất kỳ của những người khi tất cả tôi muốn thay đổi là layout_marginRight? Grrr, Android, đôi khi bạn làm tôi thất vọng quá nhiều. –

+2

Eric, bạn nên chấp nhận câu trả lời của riêng bạn làm giải pháp. –

+0

FYI Android Lint sẽ cung cấp cho bạn một lỗi (Bố cục thông số layout_height bị bỏ qua trừ khi layout_width cũng được chỉ định trên thẻ ) nếu bạn không ghi đè cả thuộc tính chiều cao và chiều rộng – binary

2

tôi thấy đôi khi tôi nhớ bao gồm cả android: thẻ id khi sử dụng GUI builder trong Eclipse. Đảm bảo (khi tôi nhận thấy) mà tôi thêm vào một TextView từ trình tạo, id tôi đang sử dụng trong bố cục ListView.

<TextView android:text="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
... 

trở thành

<TextView android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
... 

Thay vì nhận được 'false' 'false' tôi nhận được :) và bao gồm làm việc ok.

10

tôi đệ trình một enhancement request cho phép tất cả bao gồm các thuộc tính được ghi đè:

Giả sử tôi có hai bố trí giống hệt nhau khác hơn so với giá trị của một trường TextView. Hiện tại, tôi đã sửa đổi bố cục tại thời gian chạy hoặc sao chép XML.

Ví dụ để vượt qua hai tham số với các giá trị "hello" và "thế giới" để layout1:

<include layout="@layout/layout1a" params="textView=hello|editText=world" />

layout1a.xml:

<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>

An thực hiện luân phiên sẽ đóng gói phá vỡ và sẽ cho phép tuyên bố bao gồm để ghi đè các giá trị như:

<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />

layout1b.xml:

<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>

+1

không chắc chắn lý do tại sao điều này có 2 phiếu giảm giá –

+0

Cân nhắc dữ liệu mới công cụ, các ' 'được sử dụng thậm chí thường xuyên hơn bây giờ, attr trọng là một thực sự phải có tính năng –

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