package com.aincc.lib.ui.anim; import android.graphics.Camera; import android.graphics.Matrix; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Animation; import android.view.animation.Transformation; /** * * <h3><b>FlipAnimator</b></h3></br> * * @author aincc@barusoft.com * @version 1.0.0 * @since 1.0.0 */ public class FlipAnimator extends Animation { private Camera camera; private View fromView; private View toView; private float centerX; private float centerY; private boolean forward = true; private boolean visibilitySwapped; /** * * @since 1.0.0 * @param fromView * @param toView * @param centerX2 * @param centerY2 */ public FlipAnimator(View fromView, View toView, float centerX2, float centerY2) { this.fromView = fromView; this.toView = toView; this.centerX = centerX2; this.centerY = centerY2; setDuration(500); setFillAfter(true); setInterpolator(new AccelerateDecelerateInterpolator()); } /** * * @since 1.0.0 */ public void reverse() { forward = false; View tmp = toView; toView = fromView; fromView = tmp; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); camera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // Angle around the y-axis of the rotation at the given time. It is // calculated both in radians and in the equivalent degrees. final double radians = Math.PI * interpolatedTime; float degrees = (float) (180.0 * radians / Math.PI); // Once we reach the midpoint in the animation, we need to hide the // source view and show the destination view. We also need to change // the angle by 180 degrees so that the destination does not come in // flipped around. This is the main problem with SDK sample, it does not // do this. if (interpolatedTime >= 0.5f) { degrees -= 180.f; if (!visibilitySwapped) { fromView.setVisibility(View.GONE); toView.setVisibility(View.VISIBLE); visibilitySwapped = true; } } if (forward) { degrees = -degrees; } final Matrix matrix = t.getMatrix(); camera.save(); camera.translate(0.0f, 0.0f, (float) (150.0 * Math.sin(radians))); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }