Question

I have a custom View where I implement onDraw and it successfully draws the background as well as a small overlay image at the top right. I animate that overlay image (AnimationSet with a ScaleAnimation and Rotate Animation) manually by doing:

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));
                }
            }
        };
    }
});

If I invalidate the custom View like this ...

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

then the animation happens and all is great, except that the animated image now gets clipped - because it's being scaled up, beyond the top and right bounds.

But when I pass a Rect to parent.invalidate() that intersects the custom View's top right corner area, it does not trigger an onDraw for the custom View.

So ...

  • will this approach work?
  • if so, is there any other factor than the Rect passed to parent.invalidate() that determines whether it will call the custom Views onDraw method?
Was it helpful?

Solution

After a lot of searching, the answer was obvious. I just had to set the clipChildren property of the parent to false. Didn't need to invalidate the parent, just the custom View.

That worked fine on a 4.0.3 tablet. However, on a Galaxy Nexus (4.2.2), not only did it render outside of the bounds during the animation, it actually only cleared the background of the Rect passed to invalidate. So, when the animation was done some remnants of the image were still visible outside the Rect. The solution there was to pass a Rect large enough to cover the largest of the drawn bitmaps during animation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top