2

目前我面临着非常丑陋的问题。

我有几个半透明孩子的 ViewFlipper。ViewFlipper 的 In 和 Out 动画是这样制作的,以便这些孩子相互叠加(即它们的 alpha 值混合在一起)。孩子们被制作成半透明的,这样他们下面的背景就可以看到了,所以我不能为每个孩子设置背景。

问题是我现在确实希望那些孩子相交 - 稍后绘制的孩子应该被剪裁。基于这种需要,我重写了 ViewFlipper.drawChild 方法,并将动画变换矩阵应用于视图边界。接下来,我使用对先前计算的边界的补充来剪辑画布绘图区域。然而,无论我做什么,似乎仍然有一个小矩形覆盖。有什么办法可以解决吗?

我的代码如下:

public class ChartsTabsLayout extends ViewFlipper {
private Rect[] mDrawTMPParent;
private Rect mDrawTMPChild;
private Rect mDrawTMP;
private RectF mDrawTMPRectF;

public ChartsTabsLayout(final Context aContext) {
    super(aContext);
    initialize(aContext, null);
}

public ChartsTabsLayout(final Context aContext, final AttributeSet aAttributes) {
    super(aContext, aAttributes);
    initialize(aContext, aAttributes);
}

private void initialize(final Context aContext, final AttributeSet aAttributes) {
    mDrawTMPParent = new Rect[] { new Rect(), new Rect(), new Rect(), new Rect() };
    mDrawTMPChild = new Rect();
    mDrawTMP = new Rect();
    mDrawTMPRectF = new RectF();
}

@Override
protected void dispatchDraw(final Canvas aCanvas) {
    getDrawingRect(mDrawTMP);
    mDrawTMPParent[0].set(mDrawTMP);
    for(int i = 1; i < 4; i++) {
        mDrawTMPParent[i].setEmpty();
    }
    super.dispatchDraw(aCanvas);
}

private void countRectCompliment(final Rect aInside, final Rect aOutside, final Rect[] aOut) {
    for(int i = 0; i < 4; i++) {
        aOut[i].set(aOutside);
    }
    aOut[0].right = aInside.left;
    aOut[0].top = aInside.top;
    aOut[0].bottom = aInside.bottom;
    aOut[1].left = aInside.right;
    aOut[1].top = aInside.top;
    aOut[1].bottom = aInside.bottom;
    aOut[2].top = aInside.bottom;
    aOut[3].bottom = aInside.top;
    for(int i = 0; i < 4; i++) {
        if(aOut[i].left >= aOut[i].right || aOut[i].top >= aOut[i].bottom) {
            aOut[i].setEmpty();
        }
    }
}

@Override
protected boolean drawChild(final Canvas aCanvas, final View aChild, final long aDrawingTime) {
    final Transformation transformation = new Transformation();
    aChild.getDrawingRect(mDrawTMPChild);
    mDrawTMPRectF.set(mDrawTMPChild);

    final Animation animation = aChild.getAnimation();
    if(animation != null) {
        if(animation.willChangeTransformationMatrix()) {
            //if I change aDrawingTime to aDrawingTime-50 
            //animations seems to look ok, but it is "magic number" 
            //solution I would like to avoid by any means 
            animation.getTransformation(aDrawingTime, transformation); 
            transformation.getMatrix().mapRect(mDrawTMPRectF);
        }
    }
    mDrawTMPRectF.round(mDrawTMPChild);

    boolean ret = true;

    for(int i = 0; i < 4; i++) {
        if(!mDrawTMPParent[i].isEmpty()) {
            aCanvas.save();
            aCanvas.clipRect(mDrawTMPParent[i].left, mDrawTMPParent[i].top, mDrawTMPParent[i].right, mDrawTMPParent[i].bottom);
            ret |= super.drawChild(aCanvas, aChild, aDrawingTime);
            aCanvas.restore();
        }
    }
    countRectCompliment(mDrawTMPChild, mDrawTMPParent[0], mDrawTMPParent);
    return ret;
}
}
4

0 回答 0