2012-01-27 25 views
5

InsetDrawable của tôi. Tôi đang cố gắng xây dựng một LayerDrawable trong xml, nơi các lớp trên đôi khi sẽ che khuất hoàn toàn các lớp thấp hơn. Để làm cho các lớp thấp hơn nhỏ hơn, tôi đang sử dụng một InsetDrawable để bọc một drawable khác để làm cho nó nhỏ hơn kích thước đầy đủ của khung nhìn. Tuy nhiên, tôi thấy bất ngờ rằng bất kỳ lớp nào được đặt ở trên cùng của lớp chứa inset cũng có inset được áp dụng cho nó. Tôi không thể tìm thấy tài liệu hỗ trợ hành vi này, và tôi đang bối rối tại sao điều này lại xảy ra.Hành vi LayerDrawable không mong đợi khi vẽ các lớp có chứa

Trong ví dụ bên dưới, tôi tạo LayerDrawable với 3 lớp. Các lớp trên cùng và trên cùng chứa các hình dạng hình bầu dục có nghĩa là để chiếm toàn bộ khung nhìn. Tầng giữa là một hình chữ nhật có thể vẽ được bên trong một InsetDrawable. Mã này là dưới đây:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item> 
     <shape android:shape="oval" > 
      <solid android:color="#00ff00" /> 
     </shape> 
    </item> 
    <item> 
     <inset 
      android:insetBottom="4dp" 
      android:insetLeft="4dp" 
      android:insetRight="4dp" 
      android:insetTop="4dp" > 
      <shape android:shape="rectangle" > 
       <solid android:color="#ff0000" /> 
      </shape> 
     </inset> 
    </item> 
    <item> 
     <shape android:shape="oval" > 
      <solid android:color="#0000ff" /> 
     </shape> 
    </item> 

</layer-list> 

Calling setBackgroundDrawable(getResources().getDrawable(drawableId)); trong quan điểm của tôi tạo ra một hình bầu dục màu xanh lá cây lấp đầy toàn bộ quan điểm như mong đợi, với một 4dp hình chữ nhật inset đỏ như mong đợi, nhưng hình bầu dục màu xanh trên lớp trên cùng cũng là inset 4dp và được vẽ hoàn toàn trong giới hạn của hình chữ nhật màu đỏ.

Tôi hy vọng hình bầu dục màu xanh sẽ che khuất hoàn toàn hình bầu dục màu xanh lục và phần lớn hình chữ nhật màu đỏ, nhưng thay vào đó nó được chèn vào bên trong hình chữ nhật màu đỏ. Có cách nào để làm vòng tròn màu xanh lấp đầy chế độ xem nhưng vẫn giữ nó ở trên cùng không?

Trả lời

10

Tôi cũng không thấy nơi tài liệu được ghi lại, nhưng phần đệm trong một LayerDrawable được tích lũy. Đó là, đệm tại một lớp ảnh hưởng đến giới hạn của tất cả các lớp cao hơn. Đây là từ the source for LayerDrawable:

@Override 
protected void onBoundsChange(Rect bounds) { 
    final ChildDrawable[] array = mLayerState.mChildren; 
    final int N = mLayerState.mNum; 
    int padL=0, padT=0, padR=0, padB=0; 
    for (int i=0; i<N; i++) { 
     final ChildDrawable r = array[i]; 
     r.mDrawable.setBounds(bounds.left + r.mInsetL + padL, 
           bounds.top + r.mInsetT + padT, 
           bounds.right - r.mInsetR - padR, 
           bounds.bottom - r.mInsetB - padB); 
     padL += mPaddingL[i]; 
     padR += mPaddingR[i]; 
     padT += mPaddingT[i]; 
     padB += mPaddingB[i]; 
    } 
} 

(. LayerDrawable.getPadding(Rect) sau cùng một logic) Kể từ khi một InsetDrawable sử dụng insets của nó như đệm (như documented), điều này giải thích hành vi mà bạn đang nhìn thấy.

Tôi nghĩ rằng đây là một quyết định thiết kế kém, nhưng bạn đang bị mắc kẹt với nó, tôi sợ. Tôi không nghĩ rằng nó có thể bị ghi đè.

+0

Tôi đồng ý. Dường như ngược lại rằng một container có thể kéo được sẽ bị ảnh hưởng bởi một nội bộ có thể vẽ theo cách như vậy. Cảm ơn bạn đã trả lời. – happydude

+0

Có vẻ như thuộc tính 'paddingMode' đã được thêm vào để giải quyết vấn đề này. Nhưng làm cách nào chúng tôi có thể duy trì khả năng tương thích trên các nền tảng cũ hơn? – 500865

+0

Thậm chí tệ hơn trong một bộ chọn, nơi mà nó dường như ảnh hưởng đến các trạng thái khác nhau ngay cả! – JohnyTex

2

Câu trả lời của Ted là câu trả lời hay nhất, nhưng tôi sẽ chia sẻ cách giải quyết này đã giúp tôi. Tôi đã cụ thể có vấn đề đệm với một TextView, vì vậy tôi đã thực hiện một TextView tùy chỉnh thay vì bỏ qua các padding nền drawable.

public class HackTextView extends TextView { 

    public HackTextView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public HackTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public HackTextView(Context context) { 
     super(context); 
    } 

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    @Override 
    public void setBackground(Drawable background) { 
     super.setBackground(hackDrawable(background)); 
    } 

    @Override 
    public void setBackgroundDrawable(Drawable background) { 
     super.setBackgroundDrawable(hackDrawable(background)); 
    } 

    private Drawable hackDrawable(Drawable background){ 
     return new LayerDrawable(new Drawable[]{background}){ 
      @Override 
      public boolean getPadding(Rect padding) { 
       padding.set(0, 0, 0, 0); 
       return false; 
      } 
     }; 
    } 

} 
+0

Đây chính xác là những gì tôi cần. Tôi muốn một nền tùy chỉnh không phù hợp với kích thước nội dung và không ảnh hưởng đến kích thước nội dung vì tôi có hình ảnh có lề âm trên nền. Cảm ơn! – shane

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