package com.susion.boring.read.view;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.facebook.drawee.view.SimpleDraweeView;
/**
* Created by susion on 17/3/19.
* thinking by https://github.com/githubwing/DragPhotoView
*/
public class DrawScaleImageView extends SimpleDraweeView {
private Paint mPaint;
private float mDownX; // downX
private float mDownY; // down Y
private float mTranslateY;
private float mTranslateX;
private float mScale = 1;
private int mWidth;
private int mHeight;
private float mMinScale = 0.3f;
private int mAlpha = 255;
private long mTime;
private final static int MAX_TRANSLATE_Y = 500;
private final static long DURATION = 300;
public DrawScaleImageViewListener mListener;
//is event on PhotoView
private boolean isTouchEvent = false;
public DrawScaleImageView(Context context) {
this(context, null);
}
public DrawScaleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawScaleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
}
@Override
protected void onDraw(Canvas canvas) {
mPaint.setAlpha(mAlpha);
canvas.drawRect(0, 0, 2000, 3000, mPaint);
canvas.translate(mTranslateX, mTranslateY);
canvas.scale(mScale, mScale, mWidth / 2, mHeight / 2);
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
mTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
if (mTranslateY == 0 && mTranslateX != 0) { //in viewpager
//如果不消费事件,则不作操作
if (!isTouchEvent) {
restoreImageState();
}
}
//single finger drag down
if (mTranslateY >= 0 && event.getPointerCount() == 1) {
onActionMove(event);
//如果有上下位移 则不交给viewpager
if (mTranslateY != 0) {
isTouchEvent = true;
}
return true;
}
//防止下拉的时候双手缩放
if (mTranslateY >= 0 && mScale < 0.95) {
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mScale < 0.4) {
if (mListener != null) {
mListener.onExitViewImage();
}
} else {
restoreImageState();
}
break;
}
return true;
}
private void restoreImageState() {
AnimatorSet animationSet = new AnimatorSet();
animationSet.playTogether(restoreAlpha(), restoreScale(), restoreX(), restoreY());
animationSet.setDuration(300);
animationSet.start();
animationSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
if (mListener != null) {
mListener.onRestoreImageState();
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
private void onActionMove(MotionEvent event) {
float moveY = event.getY();
float moveX = event.getX();
mTranslateX = moveX - mDownX;
mTranslateY = moveY - mDownY;
//保证上划到到顶还可以继续滑动
if (mTranslateY < 0) {
mTranslateY = 0;
}
float percent = mTranslateY / MAX_TRANSLATE_Y;
if (mScale >= mMinScale && mScale <= 1f) {
mScale = 1 - percent;
mAlpha = (int) (255 * (1 - percent));
if (mAlpha > 255) {
mAlpha = 255;
} else if (mAlpha < 0) {
mAlpha = 0;
}
if (mListener != null) {
mListener.onScaleChange(mAlpha);
}
}
if (mScale < mMinScale) {
mScale = mMinScale;
} else if (mScale > 1f) {
mScale = 1;
}
invalidate();
}
private ValueAnimator restoreAlpha() {
final ValueAnimator animator = ValueAnimator.ofInt(mAlpha, 255);
animator.setDuration(DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAlpha = (int) valueAnimator.getAnimatedValue();
if (mListener != null) {
mListener.onScaleChange(mAlpha);
}
}
});
return animator;
}
private ValueAnimator restoreY() {
final ValueAnimator animator = ValueAnimator.ofFloat(mTranslateY, 0);
animator.setDuration(DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mTranslateY = (float) valueAnimator.getAnimatedValue();
}
});
return animator;
}
private ValueAnimator restoreX() {
final ValueAnimator animator = ValueAnimator.ofFloat(mTranslateX, 0);
animator.setDuration(DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mTranslateX = (float) valueAnimator.getAnimatedValue();
}
});
return animator;
}
private ValueAnimator restoreScale() {
final ValueAnimator animator = ValueAnimator.ofFloat(mScale, 1);
animator.setDuration(DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mScale = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
return animator;
}
public interface DrawScaleImageViewListener {
void onScaleChange(int alpha);
void onExitViewImage();
void onRestoreImageState();
}
public void setScaleListener(DrawScaleImageViewListener mListener) {
this.mListener = mListener;
}
}