View draw Bitmap ,放大与移动

  • Post author:
  • Post category:其他

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;
    }

});

}


版权声明:本文为xinyu391原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。