绘制包含InsetDrawable的图层时出现意外的LayerDrawable行为

hap*_*ude 5 android drawable

我试图在xml中构建一个LayerDrawable,其中上层偶尔会完全遮盖下层.为了使较低层较小,我使用InsetDrawable来包装另一个drawable,使其小于视图的完整大小.然而,我意外地发现,放置在包含插图的图层顶部的任何图层也都应用了插图.我找不到支持这种行为的文档,并且很困惑为什么会出现这种情况.

在下面的示例中,我创建了一个包含3层的LayerDrawable.底层和顶层包含椭圆形的drawables,用于占据整个视图.中间层是InsetDrawable内部的矩形绘制.代码如下:

<?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>
Run Code Online (Sandbox Code Playgroud)

setBackgroundDrawable(getResources().getDrawable(drawableId));在我的视图中调用会生成一个绿色椭圆,按预期填充整个视图,红色矩形按预期插入4dp,但顶层的蓝色椭圆也插入4dp并完全在红色矩形的边界内绘制.

我希望蓝色椭圆形能够完全遮盖绿色椭圆形和大部分红色矩形,但它会嵌入红色矩形内部.有没有办法让蓝色圆圈填满视图但仍保持在顶部?

Ted*_*opp 10

我也没有看到它被记录在哪里,但是a中的填充LayerDrawable是累积的.也就是说,一层填充会影响所有较高层的边界.这来自以下来源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];
    }
}
Run Code Online (Sandbox Code Playgroud)

(LayerDrawable.getPadding(Rect)遵循相同的逻辑.)由于InsetDrawable使用其insets作为填充(如文档所述),这解释了您所看到的行为.

我认为这是一个糟糕的设计决定,但你有点坚持它,我很害怕.我不认为它可以被覆盖.