Mark
核心要素,使用系统的ScaleGestureDetector,和GestureDetector,
对于边界处理,对4条边,依次处理,超过边界,就反向移动相应距离。
onTouchEent事件处理,优先处理多指事件
View {
onDraw(canvas ){
canvas.save(); canvas.concat(displayMatrix);
// draw bitmap
canvas.drawBitmap(displayBitmap, 0, 0, null);
canvas.restore();
}
onTouchEvent(event){
mScaleGestureDetector.onTouchEvent(event); if(!mScaleGestureDetector.isInProgress()){ moveGestureDector.onTouchEvent(event); }else{...}
// 双指放大 ScaleGestureDetector mScaleGestureDetector = new ScaleGestureDetector(getContext(),new ScaleGestureDetector.SimpleOnScaleGestureListener(){ @Override public boolean onScale(ScaleGestureDetector detector) { float factor = detector.getScaleFactor(); float x = detector.getFocusX(); float y = detector.getFocusY(); float[] values = new float[9]; displayMatrix.getValues(values); float curScale = values[Matrix.MSCALE_X]; float MaxScale = 3.0f; Matrix m = new Matrix(displayMatrix); m.postScale(factor,factor,x,y); m.getValues(values); float targetScale = values[Matrix.MSCALE_X]; if(curScale==scale && targetScale<scale){ return false; } if(curScale==MaxScale&&targetScale>MaxScale){ return false; } if (values[Matrix.MSCALE_X] < scale ){ factor = scale * factor/values[Matrix.MSCALE_X]; } if(values[Matrix.MSCALE_X]> MaxScale) { factor = MaxScale * factor/values[Matrix.MSCALE_X]; } // offsetX, offsetY; float points[]={0,0, displayBitmap.getWidth(),displayBitmap.getHeight()}; m.mapPoints(points); float dx =0; float dy = 0; // l1 > top if(points[1]>offsetY){ dy-=(points[1]-offsetY); } // l2 < right if(points[2]<getWidth()-offsetX){ dx+= (getWidth()-offsetX - points[2]); } // l3< bottom if(points[3]< getHeight()-offsetY){ dy+=(getHeight()-offsetY - points[3]); } //l4 > left if(points[0]>offsetX){ dx-= points[0]-offsetX; } displayMatrix.postScale(factor,factor, x,y); displayMatrix.postTranslate(dx,dy); postInvalidate(); return true; } }); //单指移动 final GestureDetector moveGestureDector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 未超过边界,四角padding float points[]={0,0, displayBitmap.getWidth(),displayBitmap.getHeight()}; float dx = -distanceX; float dy = -distanceY; float[] values = new float[9]; displayMatrix.getValues(values); float curScale = values[Matrix.MSCALE_X]; if(curScale==scale){//缩到最小,就不能移动了 return false; } Matrix m = new Matrix(displayMatrix); m.postTranslate(dx, dy); m.mapPoints(points); // l1 > top if(points[1]>offsetY){ dy-=(points[1]-offsetY); } // l2 < right if(points[2]<getWidth()-offsetX){ dx+= (getWidth()-offsetX - points[2]); } // l3< bottom if(points[3]< getHeight()-offsetY){ dy+=(getHeight()-offsetY - points[3]); } //l4 > left if(points[0]>offsetX){ dx-= points[0]-offsetX; } displayMatrix.postTranslate(dx,dy); postInvalidate(); return true; } });
}