package view;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import androidx.annotation.Nullable;
public class MyImageView extends ImageView {
public MyImageView(Context context) {
super(context);
// 必須設置setClickable(true), 要不然像ImageView 默認是點擊不了的,它就收不到Action_Up 事件
// 如果一個view 的onTouchEvent 的Action_Down 返回false ,那麼view的 Action_Up 是不會執行的
this.setClickable(true);
}
public MyImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.setClickable(true);
}
public MyImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setClickable(true);
}
/**
* 頂點判斷【0:中間】【1:上】【2:右】【3:下】【4:左】
**/
private int pivot = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// getX() 和 getY() 獲取的是距離自身的座標位置
startAnimDown(event.getX(), event.getY());
break;
case MotionEvent.ACTION_UP:
System.out.println("onTouchEvent :" + MotionEvent.ACTION_UP);
endAnimal();
break;
}
boolean b = super.onTouchEvent(event);
System.out.println("boolean :" + b);
return b;
}
/**
* 頂點判斷【0:中間】【1:上】【2:右】【3:下】【4:左】
**/
public OvershootInterpolator interpolator = new OvershootInterpolator(3f);
public void startAnimDown(float touchX, float touchY) {
// 獲取的是自身的相對座標位置
System.out.println("touchX :" + touchX + " touchY :" + touchY);
if (width / 5 * 2 < touchX && touchX < width / 5 * 3 && height / 5 * 2 < touchY && touchY < height / 5 * 3) {
// 代表中心位置
pivot = 0;
} else if (touchX < width / 2 && touchY < height / 2) {
if (touchX > touchY) {
pivot = 1;// 代表用戶點擊的上面
}else {
pivot = 4; // 代表用戶點擊的左邊
}
}else if (touchX < width / 2 && touchY > height / 2) {
if (touchX < (height - touchY)) {//
pivot = 4;// 代表用戶點擊左邊
}else {
pivot = 3; // 代表用戶點擊下面
}
}else if (touchX > width / 2 && touchY < height / 2){
if (width - touchX < touchY) {//點擊右邊
pivot = 2;// 點擊右邊
}else {
pivot = 1; // 代表用戶點擊上面
}
}else if (touchX > width / 2 && touchY > height / 2){
if (width - touchX > height - touchY) {//點擊下面
pivot = 3;//點擊下面
}else {
pivot = 2; // 代表用戶點擊右邊
}
}
// 上面這種算法只適合正方形的圖片
String anim = "";
System.out.println("pivot :" + pivot);
switch (pivot){
case 0:
startCenterSmallAnimal();
return;
case 1:
case 3:
anim = "rotationX";
break;
case 2:
case 4:
anim="rotationY";
break;
}
// 設置動畫的基準點
this.setPivotX(width/2);
this.setPivotY(height/2);
// 【0:中間】【1:上】【2:右】【3:下】【4:左】
if (pivot == 4 ){
endRotationValue = -7f;
}else if (pivot == 2){
endRotationValue = 7f;
}else if (pivot == 1){
endRotationValue = 7f;
}else if (pivot == 3){
endRotationValue = -7f;
}
ObjectAnimator animObject = ObjectAnimator.ofFloat(this, anim, 0, endRotationValue)
.setDuration(300);
animObject.setInterpolator(interpolator);
animObject.start();
}
private void startCenterSmallAnimal() {
int tzStart = (int) this.getTranslationZ();
this.setTag(tzStart);
PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, 0);
PropertyValuesHolder tX = PropertyValuesHolder.ofFloat("scaleX", this.getScaleX(), 0.95f);
PropertyValuesHolder tY = PropertyValuesHolder.ofFloat("scaleY", this.getScaleY(), 0.95f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,tz,tX,tY).setDuration(300);
objectAnimator.setInterpolator(interpolator);
objectAnimator.start();
}
private void startCenterBigAnimal() {
int tzValue = (int) this.getTag();
PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", 0, tzValue);
PropertyValuesHolder tX = PropertyValuesHolder.ofFloat("scaleX", this.getScaleX(), 1f);
PropertyValuesHolder tY = PropertyValuesHolder.ofFloat("scaleY", this.getScaleY(), 1f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,tz,tX,tY).setDuration(300);
objectAnimator.setInterpolator(interpolator);
objectAnimator.start();
}
// 結束動畫
public void endAnimal(){
String anim = "";
switch (pivot){
case 0:
startCenterBigAnimal();
return;
// 【0:中間】【1:上】【2:右】【3:下】【4:左】
case 1:
case 3:
anim = "rotationX";
break;
case 2:
case 4:
anim = "rotationY";
break;
}
System.out.println("pivotUp :" + pivot);
if (pivot == 2 || pivot == 4){
startRotationValue = (int) this.getRotationY();
}else {
startRotationValue = (int) this.getRotationX();
}
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this,anim,startRotationValue,0);
objectAnimator.setDuration(300);
objectAnimator.setInterpolator(interpolator);
objectAnimator.start();
}
float endRotationValue = 0;
int startRotationValue = 0;
// 當寬高發生變化時進行的回調
int height;
int width;
// System.out: touchX :552.0touchY :492.0
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
System.out.println("width :" + w + " oldWidth :" + oldw);
System.out.println("height :" + h + " oldHeight :" + oldh);
width = w;
height = h;
}
}
下面是座標位置
// 【0:中間】【1:上】【2:右】【3:下】【4:左】的算法和參考的算法不一樣
參考:https://blog.csdn.net/bamboy_/article/details/54342079