/**
* 控件的点击动画
*/
public class AnimClickUtil {
//动画执行速度
public final int ANIM_SPEED = 300;
//旋转角度
private final float POTATION_VALUE = 7f;
//变速器
public OvershootInterpolator interpolator = new OvershootInterpolator(3f);
//缩放比例
private final float SCALE_END = 0.8f;
//阴影最小值
private final float SHADOW_END = 0;
private boolean isClick; //标识点击是否有效,有效执行回掉,否则只执行动画
/**
* 启动按压动画
*
* @param view 执行动画的View
* @param superb 效果类型【true:华丽效果】【false:缩放效果】
* @param x 触点X坐标
* @param y 触点Y坐标
* @return 动画执行顶点
*/
public int startAnimDown(View view, boolean superb, float x, float y) {
if (false == view.isClickable()) {
return 1;
}
int pivot;
// 缩放效果
if (false == superb) {
pivot = 0;
// 执行缩小动画【缩放效果】
froBig_ToSmall(view);
return pivot;
}
// 华丽效果
int w = view.getWidth();
int h = view.getHeight();
if ((w / 5 * 2) < x && x < (w / 5 * 3) && (h / 5 * 2) < y && y < (h / 5 * 3)) {
pivot = 0;
} else if (x < w / 2 && y < h / 2) { // 第一象限
if (x / (w / 2) > y / (h / 2)) {
pivot = 1;
} else {
pivot = 4;
}
} else if (x < w / 2 && y >= h / 2) { // 第四象限
if ((w - x) / (w / 2) > y / (h / 2)) {
pivot = 4;
} else {
pivot = 3;
}
} else if (x >= w / 2 && y >= h / 2) { // 第三象限
if ((w - x) / (w / 2) > (h - y) / (h / 2)) {
pivot = 3;
} else {
pivot = 2;
}
} else { // 第二象限
if (x / (w / 2) > (h - y) / (h / 2)) {
pivot = 2;
} else {
pivot = 1;
}
}
String anim = "";
switch (pivot) {
case 0:
view.setPivotX(w / 2);
view.setPivotY(h / 2);
// 执行缩小动画【缩放效果】
froBig_ToSmall(view);
return pivot;
case 1:
case 3:
anim = "rotationX";
break;
case 2:
case 4:
anim = "rotationY";
break;
default:
break;
}
view.setPivotX(w / 2);
view.setPivotY(h / 2);
// 执行缩小动画【华丽效果】
froBig_ToSmall(view, pivot, anim);
return pivot;
}
/**
* 启动抬起动画
*
* @param view 执行动画的View
* @param pivot 动画执行顶点
*/
public void startAnimUp(View view, int pivot,boolean isClick) {
this.isClick = isClick;
if (false == view.isClickable()) {
return;
}
if (pivot == 0) {
// 执行放大动画【缩放效果】
froSmall_ToBig(view);
} else {
String anim = "";
switch (pivot) {
case 1:
case 3:
anim = "rotationX";
break;
case 2:
case 4:
anim = "rotationY";
break;
}
// 执行放大动画【华丽效果】
froSmall_ToBig(view, pivot, anim);
}
}
/**
* 【华丽效果】从大过渡到小
*/
private void froBig_ToSmall(View view, int pivot, String anim) {
float potationEnd;
if (pivot == 3 || pivot == 4) {
potationEnd = 0 - POTATION_VALUE;
} else {
potationEnd = POTATION_VALUE;
}
int potationStart = 0;
if (pivot == 2 || pivot == 4) {
potationStart = (int) view.getRotationY();
} else {
potationStart = (int) view.getRotationX();
}
ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potationStart, potationEnd)
.setDuration(ANIM_SPEED);
animObject.setInterpolator(interpolator);
animObject.start();
}
/**
* 【华丽效果】从小过渡到大
*/
private void froSmall_ToBig(View view, int pivot, String anim) {
int potation;
if (pivot == 2 || pivot == 4) {
potation = (int) view.getRotationY();
} else {
potation = (int) view.getRotationX();
}
ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potation, 0).setDuration(ANIM_SPEED);
animObject.setInterpolator(interpolator);
animObject.start();
}
/**
* 【缩放效果】从大过渡到小
*/
public void froBig_ToSmall(View view) {
try {
float tzStart = 0;
Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);
if (android.os.Build.VERSION.SDK_INT >= 21) {
tzStart = view.getTranslationZ();
if (viewTag == null || false == viewTag instanceof Float) {
view.setTag(R.string.anim_click_tag_key_translation_z, tzStart);
}
}
//控件的长宽高执行缩小动画
PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, SHADOW_END);
PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), SCALE_END);
PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), SCALE_END);
ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);
animatorD.setInterpolator(interpolator);
animatorD.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//动画结束时的回掉
if (listener1 != null && isClick) {
listener1.onDownEnd();
}
}
});
animatorD.start();
} catch (Exception e) {
}
}
/**
* 【缩放效果】从小过渡到大
*/
public void froSmall_ToBig(View view) {
try {
float tzStart = 0, tzEnd = 0;
Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);
if (android.os.Build.VERSION.SDK_INT >= 21) {
tzStart = view.getTranslationZ();
if (viewTag != null && viewTag instanceof Float) {
tzEnd = (Float) viewTag;
}
}
//控件的长宽高执行缩小后的恢复动画
PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, tzEnd);
PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), 1);
PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), 1);
ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);
animatorD.setInterpolator(interpolator);
animatorD.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//动画结束时的回掉
if (listener1 != null && isClick) {
listener1.onUpEnd();
}
}
});
animatorD.start();
} catch (Exception e) {
}
}
public interface OnAnimEndListener {
void onDownEnd();
void onUpEnd();
}
public OnAnimEndListener listener1;
public void setAnimEndListener(OnAnimEndListener listener) {
listener1 = listener;
}
}
/***
* 只要控件外层套上该控件,即可实现点击动画
*/
public class AnimRelativeLayout extends RelativeLayout {
/**
* 动画模式【true:华丽效果——缩放加方向】【false:只缩放】
* 华丽效果:即点击控件的 上、下、左、右、中间时的效果都不一样
* 普通效果:即点击控件的任意部位,都只是缩放效果,与 华丽效果模式下 点击控件中间时的动画一样
**/
private boolean superb = false;
/**
* 顶点判断【0:中间】【1:上】【2:右】【3:下】【4:左】
**/
private int pivot = 0;
private AnimClickUtil bamAnim;
public AnimRelativeLayout(Context context) {
this(context,null);
this.setClickable(true);
}
public AnimRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
this.setClickable(true);
}
public AnimRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setClickable(true);
initView();
}
private void initView() {
bamAnim = new AnimClickUtil();
}
/**
* 打开/关闭华丽效果,默认时关闭的
*/
public void openSuperb(boolean isOpen) {
superb = isOpen;
}
@Override
@SuppressLint("ClickableViewAccessibility")
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pivot = bamAnim.startAnimDown(this, superb, event.getX(), event.getY());
break;
case MotionEvent.ACTION_CANCEL:
bamAnim.startAnimUp(this, pivot,false);
break;
case MotionEvent.ACTION_UP:
bamAnim.startAnimUp(this, pivot,true);
break;
default:
break;
}
return super.onTouchEvent(event);
}
public void setDownEndListener(AnimClickUtil.OnAnimEndListener listener) {
bamAnim.setAnimEndListener(listener);
}
使用方式:直接在外层嵌套Layout即可。
效果如下: