0
votes

This is an odd one. I have an animation that flips a view 90 degrees and then another view is rotated the other 90 degrees, allowing for a change of image. This works and it works well on the Samsung Tab 3; however on the Tab 4 the animation is very jerky. If I turn on the 'Profile GPU rendering' - 'Show on screen as bars' the animation becomes very smooth.

I have put debug logs in the animation, and I have found the applyTransformation function is called the same amount of times, when it is jerky and when it is smooth. So all I can put it down to is the screen isn't being refreshed enough. Any thoughts would be great.

Here is the Flip animation. public class AnimatedFlip extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private Camera mCamera;

    public AnimatedFlip(float aFromDegrees, float aToDegrees, float aCenterX, float aCenterY)
    {
        mFromDegrees = aFromDegrees;
        mToDegrees = aToDegrees;
        mCenterX = aCenterX;
        mCenterY = aCenterY;
    }

    @Override
    public void initialize(int aWidth, int aHeight, int aParentWidth, int aParentHeight)
    {
        super.initialize(aWidth, aHeight, aParentWidth, aParentHeight);
        mCamera = new Camera();
    }

    @Override
    protected void applyTransformation(float aInterpolatedTime, Transformation aTransformation)
    {
        float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * aInterpolatedTime);

        final Matrix matrix = aTransformation.getMatrix();

        mCamera.save();
        mCamera.rotateY(degrees);
        mCamera.getMatrix(matrix);
        mCamera.restore();

        matrix.preTranslate(-mCenterX, -mCenterY);
        matrix.postTranslate(mCenterX, mCenterY);
    }
}

The animation is started with this call.

mFlipStartingView.setVisibility(View.VISIBLE);
applyRotation(0, 90, mFlipStartingView);

This is the function that does the animation.

private void applyRotation(float aStart, float aEnd, final ImageView aView)
{
    // Find the center of image
    float centerX = aView.getWidth() / 2.0f + aView.getX();
    float centerY = aView.getHeight() / 2.0f + aView.getY();

    // Create a new 3D rotation with the supplied parameter
    // The animation listener is used to trigger the next animation
    final AnimatedFlip rotation = new AnimatedFlip(aStart, aEnd, centerX, centerY);
    rotation.setDuration(mFlipAnimationTime);
    rotation.setFillAfter(false);
    rotation.setInterpolator(new LinearInterpolator());
    rotation.setAnimationListener(new Animation.AnimationListener()
    {
        @Override public void onAnimationStart(Animation animation)
        {
        }

        @Override public void onAnimationEnd(Animation animation)
        {
            if (aView != mFlipView)
            {
                mFlipStartingView.setVisibility(View.INVISIBLE);
                mFlipView.setVisibility(View.VISIBLE);
                applyRotation(-89, 0, mFlipView);
            }
        }

        @Override public void onAnimationRepeat(Animation animation)
        {
        }
    });
    aView.startAnimation(rotation);
}
1

1 Answers

0
votes

So I have added a Hack to make this work on the Tab4. At the end of the apply rotation function I have added the following code.

    // hack for the Tab 4
    new CountDownTimer(mFlipAnimationTime * 2, 33)
    {
        @Override public void onTick(long millisUntilFinished)
        {
            mFlipView.refreshDrawableState();
            mFlipView.invalidate();
            mFlipStartingView.refreshDrawableState();
            mFlipStartingView.invalidate();
        }

        @Override public void onFinish()
        {
            mFlipView.refreshDrawableState();
            mFlipView.invalidate();
            mFlipStartingView.refreshDrawableState();
            mFlipStartingView.invalidate();
        }
    }.start();

This makes sure the animation views are updated at least ever 1/30 of a second.