View缩放。根据两指连线的中点为缩放中心进行缩放。
SacleGesture.java
1
2 3 import android.view.ScaleGestureDetector; 4 import android.view.View; 5 import android.view.ScaleGestureDetector.OnScaleGestureListener; 6 import android.view.animation.Animation; 7 import android.view.animation.ScaleAnimation; 8 9 /** 10 * scale gesture helper.</br> 11 * please invoke {@link ScaleGesture#setSourceView(View)} before dispatch touch event.</br> 12 * if {@link ScaleGesture#setFillAfter(boolean)} parameter is true that keeping same scale when next scaling.</br> 13 * sample code: 14 * <pre> 15 * ScaleGesture sg = new ScaleGesture(); 16 * ScaleGestureDetector detector = new ScaleGestureDetector(getContext(), sg); 17 * ... 18 * sg.setSourceView(...); 19 * ... 20 * onTouchEvent(MotionEvent) { 21 * ... 22 * detector.onTouchEvent(event); 23 * ... 24 * } 25 * </pre> 26 * 27 * @author bin 28 * 29 */ 30 public class ScaleGesture implements OnScaleGestureListener { 31 32 private float beforeFactor; 33 private float mPivotX; 34 private float mPivotY; 35 private View mVSouce; 36 private boolean isFillAfter; 37 38 public void setSourceView(View destinyView) { 39 mVSouce = destinyView; 40 } 41 42 @Override 43 public boolean onScale(ScaleGestureDetector detector) { 44 if (checkIsNull()) { 45 return false; 46 } 47 final float factor = detector.getScaleFactor(); 48 Animation animation = new ScaleAnimation(beforeFactor, factor, 49 beforeFactor, factor, mPivotX , mPivotY); 50 animation.setFillAfter(true); 51 mVSouce.startAnimation(animation); 52 beforeFactor = factor; 53 return false; 54 } 55 56 @Override 57 public boolean onScaleBegin(ScaleGestureDetector detector) { 58 if (checkIsNull()) { 59 return false; 60 } 61 beforeFactor = 1f; 62 mPivotX = detector.getFocusX() - mVSouce.getLeft(); 63 mPivotY = mVSouce.getTop() + (mVSouce.getHeight() >> 1); 64 return true; 65 } 66 67 @Override 68 public void onScaleEnd(ScaleGestureDetector detector) { 69 if (checkIsNull()) { 70 return; 71 } 72 final float factor = detector.getScaleFactor(); 73 final int nWidth = (int) (mVSouce.getWidth() * factor); 74 final int nHeight = (int) mVSouce.getHeight(); 75 final int nLeft = (int) (mVSouce.getLeft() - ((nWidth - mVSouce.getWidth()) * 76 (mPivotX / mVSouce.getWidth()))); 77 final int nTop = (int) mVSouce.getTop(); 78 if (isFillAfter) { 79 mVSouce.layout(nLeft, nTop, nLeft + nWidth, nTop + nHeight); 80 } 81 // MUST BE CLEAR ANIMATION. OTHERWISE WILL BE FLICKER 82 mVSouce.clearAnimation(); 83 } 84 85 public boolean checkIsNull() { 86 return mVSouce == null ? true : false; 87 } 88 89 /** 90 * if parameter is true that keeping same scale when next scaling. 91 * @param isFill 92 */ 93 public void setFillAfter(boolean isFill) { 94 isFillAfter = isFill; 95 } 96 }