/**
* 控件的點擊動畫
*/
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即可。
效果如下: