1

我有一个自定义视图,我在其中实现了 onDraw,它成功地绘制了背景以及右上角的小覆盖图像。我通过执行以下操作手动为叠加图像(带有 ScaleAnimation 和 Rotate Animation 的动画集)设置动画:

final AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotationAnimation);
animationSet.setFillAfter(true);
post(new Runnable() {
    @Override
    public void run () {
        animationSet.start();
        new Handler().post(getAnimationRunnable(animationSet));
    }

    private Runnable getAnimationRunnable (final AnimationSet animationSet) {
        return new Runnable() {
            @Override
            public void run () {
                final Transformation outTransformation = new Transformation();
                if (animationSet.getTransformation(System.currentTimeMillis(), outTransformation)) {
                    // store matrix for applying in onDraw
                    mMatrix = outTransformation.getMatrix();
                    // THIS INVALIDATE DOESN'T WORK
                    parent.invalidate(new Rect(getParentInvalidateRect()));
                    post(getAnimationRunnable(animationSet));
                }
            }
        };
    }
});

如果我像这样使自定义视图无效...

                    // THIS INVALIDATE DOES WORK
                    invalidate(getOverlayClientRect());

然后动画发生了,一切都很好,除了动画图像现在被剪裁了——因为它被放大了,超出了顶部和右侧的边界。

但是,当我将 Rect 传递给与自定义 View 的右上角区域相交的 parent.invalidate() 时,它不会触发自定义 View 的 onDraw。

所以 ...

  • 这种方法会奏效吗?
  • 如果是这样,除了传递给 parent.invalidate() 的 Rect 之外,是否还有其他因素决定它是否会调用自定义视图的 onDraw 方法?
4

1 回答 1

1

经过大量搜索,答案很明显。我只需要将父级的 clipChildren 属性设置为 false。不需要使父级无效,只需自定义视图。

这在 4.0.3 平板电脑上运行良好。然而,在 Galaxy Nexus (4.2.2) 上,它不仅在动画期间渲染到边界之外,它实际上只是清除了传递给无效的 Rect 的背景。因此,当动画完成时,图像的一些残余部分在 Rect 之外仍然可见。解决方案是传递一个足够大的 Rect 以覆盖动画期间绘制的最大位图。

于 2013-07-18T16:39:29.093 回答