Android卡牌翻转动画效果实现
简述
之前项目有个需求,需要实现卡牌翻转效果,自己试着写过,效果不是很好,后来找到了一个Rotatable-master的项目,使用里面提供的类实现了卡牌翻转的效果。默认情况下,翻转动画卡牌在动画进行中的拉伸变形幅度会很大,可以通过setCameraDistance方法来改变控件的应该说是观察点距离吧,让观察点远一点,这样反转动画看起来会舒服一点。
效果图
代码
.java 旋转工具类
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.support.annotation.IntDef;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.DisplayMetrics;
import android.util.Property;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.CycleInterpolator;
import java.util.ArrayList;
/**
* 旋转工具类
* Created by Yahya Bayramoglu on 01/12/15.
*/
public class Rotatable implements View.OnTouchListener {
private static final int NULL_INT = -1;
private final int FIT_ANIM_TIME = 300;
public static final int DEFAULT_ROTATE_ANIM_TIME = 500;
public static final int ROTATE_BOTH = 0;
public static final int ROTATE_X = 1;
public static final int ROTATE_Y = 2;
@IntDef({ROTATE_X, ROTATE_Y, ROTATE_BOTH})
public @interface Direction {
}
public static final int FRONT_VIEW = 3;
public static final int BACK_VIEW = 4;
@IntDef({FRONT_VIEW, BACK_VIEW})
public @interface Side {
}
private RotationListener rotationListener;
private View rootView, frontView, backView;
private boolean touchEnable = true;
private boolean shouldSwapViews = false;
private int rotation;
private int screenWidth = NULL_INT, screenHeight = NULL_INT;
private int currentVisibleView = FRONT_VIEW;
private float rotationCount;
private float rotationDistance;
private float oldX, oldY, currentX, currentY;
private float currentXRotation = 0, currentYRotation = 0;
private float maxDistanceX = NULL_INT, maxDistanceY = NULL_INT;
private float defaultPivotX = NULL_INT, defaultPivotY = NULL_INT;
private Rotatable(Builder builder) {
this.rootView = builder.root;
this.defaultPivotX = rootView.getPivotX();
this.defaultPivotY = rootView.getPivotY();
this.rotationListener = builder.listener;
if (builder.pivotX != NULL_INT) {
this.rootView.setPivotX(builder.pivotX);
}
if (builder.pivotY != NULL_INT) {
this.rootView.setPivotY(builder.pivotY);
}
if (builder.frontId != NULL_INT) {
this.frontView = rootView.findViewById(builder.frontId);
}
if (builder.backId != NULL_INT) {
this.backView = rootView.findViewById(builder.backId);
}
this.rotation = builder.rotation;
this.rotationCount = builder.rotationCount;
this.rotationDistance = builder.rotationDistance;
this.shouldSwapViews = frontView != null && backView != null;
rootView.setOnTouchListener(this);
}
/**
* This method needs to be call, if only you need to reset and
* rebuild a view as rotatable with different configurations
*/
public void drop() {
rootView.setPivotX(defaultPivotX);
rootView.setPivotY(defaultPivotY);
rootView.setOnTouchListener(null);
rootView = null;
frontView = null;
backView = null;
}
/**
* You can specify rotation direction as axis X, Y or BOTH
*/
public void setDirection(@Direction int direction) {
if (!isRotationValid(direction)) {
throw new IllegalArgumentException("Cannot specify given value as rotation direction!");
}
this.rotation = direction;
}
/**
* You may need to enable / disable touch interaction at some point,
* so it is possible to do it so anytime by rotatable object
*/
public void setTouchEnable(boolean enable) {
this.touchEnable = enable;
}
/**
* To determine rotatable object is currently touchable or not
*/
public boolean isTouchEnable() {
return touchEnable;
}
/**
* If your application can be used multi orientated, then you have to declare
* orientation changes to rotatable object, so it can recalculate its maxDistances.
* <p>
* You only need to inform rotatable object about orientation changes, when you specified
* {@link Builder#rotationCount(float)} or {@link Builder#rotationDistance(float)}
*/
public void orientationChanged(int newOrientation) {