Example #1
0
 // 记录缩放前的一些信息
 private void saveScaleContext(float x1, float y1, float x2, float y2) {
   mScaleBase = MathUtils.getMatrixScale(mOuterMatrix)[0] / MathUtils.getDistance(x1, y1, x2, y2);
   // 获取缩放缩放点中点在第一层变换后的图片上的坐标
   float[] center =
       MathUtils.inverseMatrixPoint(MathUtils.getCenterPoint(x1, y1, x2, y2), mOuterMatrix);
   mScaleCenter.set(center[0], center[1]);
 }
Example #2
0
 // 当缩放操作结束如果不在正确位置用动画恢复
 private void scaleEnd() {
   // 不允许动画过程中再触发
   if ((mScaleAnimator != null && mScaleAnimator.isRunning()) || getDrawable() == null) {
     return;
   }
   // 是否修正了位置
   boolean change = false;
   // 获取图片整体的变换矩阵
   Matrix currentMatrix = getCurrentImageMatrix();
   // 整体缩放比例
   float currentScale = MathUtils.getMatrixScale(currentMatrix)[0];
   // 第二层缩放比例
   float outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0];
   // 控件大小
   float displayWidth = getMeasuredWidth();
   float displayHeight = getMeasuredHeight();
   float maxScale = getMaxScale();
   // 比例修正
   float scalePost = 1;
   // 位置修正
   float postX = 0;
   float postY = 0;
   // 如果整体缩放比例大于最大比例,进行缩放修正
   if (currentScale > maxScale) {
     scalePost = maxScale / currentScale;
   }
   // 如果缩放修正后整体导致第二层缩放小于1(就是图片比fit center状态还小),重新修正缩放
   if (outerScale * scalePost < 1) {
     scalePost = 1 / outerScale;
   }
   // 如果修正不为1,说明进行了修正
   if (scalePost != 1) {
     change = true;
   }
   // 尝试根据缩放点进行缩放修正
   Matrix testMatrix = new Matrix(currentMatrix);
   testMatrix.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y);
   RectF testBound =
       new RectF(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
   // 获取缩放修正后的图片方框
   testMatrix.mapRect(testBound);
   // 检测缩放修正后位置有无超出,如果超出进行位置修正
   if (testBound.right - testBound.left < displayWidth) {
     postX = displayWidth / 2 - (testBound.right + testBound.left) / 2;
   } else if (testBound.left > 0) {
     postX = -testBound.left;
   } else if (testBound.right < displayWidth) {
     postX = displayWidth - testBound.right;
   }
   if (testBound.bottom - testBound.top < displayHeight) {
     postY = displayHeight / 2 - (testBound.bottom + testBound.top) / 2;
   } else if (testBound.top > 0) {
     postY = -testBound.top;
   } else if (testBound.bottom < displayHeight) {
     postY = displayHeight - testBound.bottom;
   }
   // 如果位置修正不为0,说明进行了修正
   if (postX != 0 || postY != 0) {
     change = true;
   }
   // 只有有执行修正才执行动画
   if (change) {
     // 如果up的时候触发惯性,这里需要取消掉,以修正动画为主
     if (mFlingAnimator != null) {
       mFlingAnimator.cancel();
       mFlingAnimator = null;
     }
     // 动画开始举证
     Matrix animStart = new Matrix(mOuterMatrix);
     // 计算结束举证
     Matrix animEnd = new Matrix(mOuterMatrix);
     animEnd.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y);
     animEnd.postTranslate(postX, postY);
     // 启动矩阵动画
     mScaleAnimator = new ScaleAnimator(animStart, animEnd);
     mScaleAnimator.start();
   }
 }
Example #3
0
 // 双击后放大或者缩小
 // 当当前缩放比例大于等于1,那么双击放大到MaxScale
 // 当当前缩放比例小于1,双击放大到1
 // 当当前缩放比例等于MaxScale,双击缩小到屏幕大小
 private void doubleTap(float x, float y) {
   // 不允许动画过程中再触发
   if ((mScaleAnimator != null && mScaleAnimator.isRunning()) || getDrawable() == null) {
     return;
   }
   // 获取第一层变换矩阵
   Matrix innerMatrix = getInnerMatrix();
   // 当前总的缩放比例
   float innerScale = MathUtils.getMatrixScale(innerMatrix)[0];
   float outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0];
   float currentScale = innerScale * outerScale;
   // 控件大小
   float displayWidth = getMeasuredWidth();
   float displayHeight = getMeasuredHeight();
   // 最大放大大小
   float maxScale = getMaxScale();
   // 接下来要放大的大小
   float nextScale = calculateNextScale(innerScale, outerScale);
   // 如果接下来放大大于最大值或者小于fit center值,则取边界
   if (nextScale < innerScale) {
     nextScale = innerScale;
   } else if (nextScale > maxScale) {
     nextScale = maxScale;
   }
   // 缩放动画初始矩阵为当前矩阵值
   Matrix animStart = new Matrix(mOuterMatrix);
   // 开始计算缩放动画的结果矩阵
   Matrix animEnd = new Matrix(mOuterMatrix);
   // 计算还需缩放的倍数
   animEnd.postScale(nextScale / currentScale, nextScale / currentScale, x, y);
   // 将放大点移动到控件中心
   animEnd.postTranslate(displayWidth / 2 - x, displayHeight / 2 - y);
   // 得到放大之后的图片方框
   Matrix testMatrix = new Matrix(innerMatrix);
   testMatrix.postConcat(animEnd);
   RectF testBound =
       new RectF(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
   testMatrix.mapRect(testBound);
   // 修正位置
   float postX = 0;
   float postY = 0;
   if (testBound.right - testBound.left < displayWidth) {
     postX = displayWidth / 2 - (testBound.right + testBound.left) / 2;
   } else if (testBound.left > 0) {
     postX = -testBound.left;
   } else if (testBound.right < displayWidth) {
     postX = displayWidth - testBound.right;
   }
   if (testBound.bottom - testBound.top < displayHeight) {
     postY = displayHeight / 2 - (testBound.bottom + testBound.top) / 2;
   } else if (testBound.top > 0) {
     postY = -testBound.top;
   } else if (testBound.bottom < displayHeight) {
     postY = displayHeight - testBound.bottom;
   }
   // 应用修正位置
   animEnd.postTranslate(postX, postY);
   // 如果正在执行惯性动画,则取消掉
   if (mFlingAnimator != null) {
     mFlingAnimator.cancel();
     mFlingAnimator = null;
   }
   // 启动矩阵动画
   mScaleAnimator = new ScaleAnimator(animStart, animEnd);
   mScaleAnimator.start();
 }