游戏截图支持缩放

This commit is contained in:
khy
2016-10-27 19:00:34 +08:00
parent 929038fc30
commit 96e59d764a
7 changed files with 401 additions and 24 deletions

View File

@ -0,0 +1,279 @@
package com.gh.common.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.gamecenter.eventbus.EBReuse;
import de.greenrobot.event.EventBus;
/**
* Created by khy on 2016/10/26.
*/
public class ZoomSimpleDraweeView extends SimpleDraweeView {
private ScaleGestureDetector mScaleDetector;
private GestureDetector mGestureDetector;
private float mCurrentScale = 1f;
private Matrix mCurrentMatrix;
private setOnSingleClickListener mClickListener;
private float imgagePro = -1; // 图片宽高比
public ZoomSimpleDraweeView(Context context) {
super(context);
init();
}
public ZoomSimpleDraweeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ZoomSimpleDraweeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mCurrentMatrix = new Matrix();
ScaleGestureDetector.OnScaleGestureListener scaleListener = new ScaleGestureDetector
.SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
if (mCurrentScale < 4f || detector.getScaleFactor() < 1f){
mCurrentScale *= scaleFactor;
mCurrentMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
invalidate();
}
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
super.onScaleEnd(detector);
if (mCurrentScale < 1f) {
reset();
}
checkBorder();
}
};
mScaleDetector = new ScaleGestureDetector(getContext(), scaleListener);
GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (mClickListener != null) {
mClickListener.onClick();
}
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (mCurrentScale > 1f) {
mCurrentMatrix.postTranslate(-distanceX, -distanceY);
invalidate();
checkBorder();
}
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
final float x = e.getX();
final float y = e.getY();
float scaleSize ; //扩大或缩小的倍数
if (mCurrentScale > 1.5f){ //缩小时直接回到原画大小
scaleSize = 0.5f;
ZoomSimpleDraweeView.this.post(new AutoScaleRunnable(mCurrentScale * scaleSize, getWidth() / 2f, getHeight() / 2f, false));
} else {
scaleSize = 2.0f;
ZoomSimpleDraweeView.this.post(new AutoScaleRunnable(mCurrentScale * scaleSize, x, y, true));
}
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return super.onSingleTapUp(e);
}
};
mGestureDetector = new GestureDetector(getContext(), gestureListener);
}
/**
* 检查图片边界是否移到view以内
* 目的是让图片边缘不要移动到view里面
*/
private void checkBorder() {
RectF rectF = getDisplayRect(mCurrentMatrix);
boolean reset = false;
float dx = 0;
float dy = 0;
if (rectF.left > 0) {
dx = getLeft() - rectF.left;
reset = true;
}
if (rectF.top > 0) {
dy = getTop() - rectF.top;
reset = true;
}
if (rectF.right < getRight()) {
dx = getRight() - rectF.right;
reset = true;
}
if (rectF.bottom < getHeight()) {
dy = getHeight() - rectF.bottom;
reset = true;
}
if (reset) {
mCurrentMatrix.postTranslate(dx, dy);
invalidate();
}
if (dy == 0 && reset || mCurrentScale == 1f){
EventBus.getDefault().post(new EBReuse("isStopMove"));
} else{
EventBus.getDefault().post(new EBReuse("isStartove"));
}
}
/**
* Helper method that maps the supplied Matrix to the current Drawable
*
* @param matrix - Matrix to map Drawable against
* @return RectF - Displayed Rectangle
*/
private RectF getDisplayRect(Matrix matrix) {
// int bottom;
// if (imgagePro != -1){
// bottom = (int) (getRight()*imgagePro);
// } else {
// bottom = getBottom();
// }
RectF rectF = new RectF(getLeft(), getTop(), getRight(), getBottom());
matrix.mapRect(rectF);
return rectF;
}
@Override
public void setImageURI(Uri uri) {
reset();
super.setImageURI(uri);
}
@Override
protected void onDraw(Canvas canvas) {
int saveCount = canvas.save();
canvas.concat(mCurrentMatrix);
super.onDraw(canvas);
canvas.restoreToCount(saveCount);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mScaleDetector.onTouchEvent(event);
if (!mScaleDetector.isInProgress()) {
mGestureDetector.onTouchEvent(event);
}
return true;
}
/**
* 重置图片
*/
public void reset() {
mCurrentMatrix.reset();
mCurrentScale = 1f;
invalidate();
EventBus.getDefault().post(new EBReuse("isStopMove"));
}
private final float[] matrixValues = new float[9];
public final float getScale() {
mCurrentMatrix.getValues(matrixValues);
return matrixValues[Matrix.MSCALE_X];
}
/**
* 自动缩放的任务
*/
private class AutoScaleRunnable implements Runnable {
static final float BIGGER = 1.07f;
static final float SMALLER = 0.96f;
private float mTargetScale;
private boolean isExp;
/**
* 缩放的中心
*/
private float x;
private float y;
/**
* @param isExp :判断是否是放大
*/
public AutoScaleRunnable(float targetScale, float x, float y, boolean isExp) {
this.mTargetScale = targetScale;
this.x = x;
this.y = y;
this.isExp = isExp;
}
@Override
public void run() {
if (isExp){ //放大
mCurrentMatrix.postScale(BIGGER, BIGGER, x, y);
invalidate();
if (mCurrentScale < mTargetScale && mCurrentScale <= 4) {
ZoomSimpleDraweeView.this.postDelayed(this, 10);
mCurrentScale = mCurrentScale * BIGGER;
} else {
checkBorder();
mCurrentScale = getScale();
}
}else {//缩小
mCurrentMatrix.postScale(SMALLER, SMALLER, x, y);
invalidate();
checkBorder();
if (getScale() > 1.01) {
ZoomSimpleDraweeView.this.postDelayed(this, 1);
mCurrentScale = mCurrentScale * SMALLER;
} else {
reset();
}
}
}
}
//图片宽高比例
public void setImagePro (float imgPro){
this.imgagePro = imgPro;
}
public void setOnSingleClickListener(setOnSingleClickListener listener) {
mClickListener = listener;
}
public interface setOnSingleClickListener {
void onClick();
}
}