Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 画布在收缩到缩放后手指绘制坐标错误_Android_Android Canvas_Pinchzoom_Scaletransform - Fatal编程技术网

Android 画布在收缩到缩放后手指绘制坐标错误

Android 画布在收缩到缩放后手指绘制坐标错误,android,android-canvas,pinchzoom,scaletransform,Android,Android Canvas,Pinchzoom,Scaletransform,我创建了画布手指绘图应用程序,如线上画笔,我做了收缩缩放功能,但问题是在放大和缩小后,并没有正确地在画布区域上绘制位置。为了进一步了解,我共享了画布绘图的视图类: public class DrawingView extends View { // Zooming Code 16-6-2015 4.12pm private static final int INVALID_POINTER_ID = -1; public Bitmap mMyChracter; p

我创建了画布手指绘图应用程序,如线上画笔,我做了收缩缩放功能,但问题是在放大和缩小后,并没有正确地在画布区域上绘制位置。为了进一步了解,我共享了画布绘图的视图类:

public class DrawingView extends View {

//  Zooming Code 16-6-2015 4.12pm

    private static final int INVALID_POINTER_ID = -1;
     public Bitmap mMyChracter;
     private float mPosX;
     private float mPosY;

     private float mLastTouchX;
     private float mLastTouchY;
     private int mActivePointerId = INVALID_POINTER_ID;

     View currentView;
     private ScaleGestureDetector mScaleDetector;
     private float mScaleFactor = 1.f;

     private float focusX;
     private float focusY;

     private float lastFocusX = -1;
     private float lastFocusY = -1;

     static final int IMG_WIDTH = 640;
     static final int IMG_HEIGHT = 480;

     static final int IMAGE_X_POS = 560;
     static final int IMAGE_Y_POS = 20;

     float sy;
     float sx;
     public static Context context;
//   -------------------------------------


//   ...................................

        /*private final Bitmap bitmap;
        private final int width;
        private final int height;*/

        private Matrix transform = new Matrix();

        private Vector2D position = new Vector2D();
        private float scale = 1;
        private float angle = 0;

        private TouchManager touchManager = new TouchManager(2);
        private boolean isInitialized = false;

        // Debug helpers to draw lines between the two touch points
        private Vector2D vca = null;
        private Vector2D vcb = null;
        private Vector2D vpa = null;
        private Vector2D vpb = null;
        int mWidth;
        int mHeight;
//      ...............................

    private final Paint mDefaultPaint;

    private Paint mFillPaint;
    float x, y;
    private Canvas mLayerCanvas = new Canvas();
    private Bitmap mLayerBitmap;

    private Stack<DrawOp> mDrawOps = new Stack<>();
    private Stack<DrawOp> mUndoOps = new Stack<>();

    private SparseArray<DrawOp> mCurrentOps = new SparseArray<>(0);


//  For Drag and Pan zoom Code initialization
    private static float MIN_ZOOM = 1f;

    private static float MAX_ZOOM = 2f;
    private float scaleFactor = 1.f;

    private static ScaleGestureDetector detector; 

    boolean mFlagDrawing;

    private final Matrix mMatrix = new Matrix();

     int y_old=0,y_new=0;int zoomMode=0;
     float pinch_dist_old=0,pinch_dist_new=0;
     int zoomControllerScale=1;//new and old pinch distance to determine Zoom scale
        // These matrices will be used to move and zoom image
        Matrix matrix = new Matrix();
        Matrix savedMatrix = new Matrix();

        // Remember some things for zooming
        PointF start = new PointF();
        PointF mid = new PointF();
        float oldDist = 1f;

        // We can be in one of these 3 states
        static final int NONE = 0;
        static final int PAN = 1;
        static final int ZOOM = 2;
        int mode = NONE;

     private static final String TAG = "DebugTag";



//     New Code
     private Bitmap imgBitmap = null;

     private int containerWidth;
     private int containerHeight;

     Paint background;   

     //Matrices will be used to move and zoom image
//     Matrix matrix = new Matrix();
//     Matrix savedMatrix = new Matrix();

//     PointF start = new PointF();       

     float currentScale;
     float curX;
     float curY;

     //We can be in one of these 3 states
//     static final int NONE = 0;
//     static final int DRAG = 1;
//     static final int ZOOM = 2;
//     int mode = NONE;

     //For animating stuff   
     float targetX;
     float targetY;
     float targetScale;
     float targetScaleX;
     float targetScaleY;
     float scaleChange;
     float targetRatio;
     float transitionalRatio;

     float easing = 0.2f;   
     boolean isAnimating = false;

     float scaleDampingFactor = 0.5f;

     //For pinch and zoom
//     float oldDist = 1f;   
//     PointF mid = new PointF();

     private Handler mHandler = new Handler();       

     float minScale;
     float maxScale = 8.0f;

     float wpRadius = 25.0f;
     float wpInnerRadius = 20.0f;

     float screenDensity;

     private GestureDetector gestureDetector;

     public static final int DEFAULT_SCALE_FIT_INSIDE = 0;
     public static final int DEFAULT_SCALE_ORIGINAL = 1;

     private int defaultScale;


     private static final String EXTRA_EVENT_LIST = "event_list";
     private static final String EXTRA_STATE = "instance_state";
     private ArrayList<MotionEvent> eventList = new ArrayList<MotionEvent>(100);

    public DrawingView(Context context) {
        this(context, null, 0);
    }

    public DrawingView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
//      detector = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    public DrawingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mDefaultPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mDefaultPaint.setStyle(Paint.Style.STROKE);
        mDefaultPaint.setStrokeJoin(Paint.Join.ROUND);
        mDefaultPaint.setStrokeCap(Paint.Cap.ROUND);
        mDefaultPaint.setStrokeWidth(40);
        mDefaultPaint.setColor(Color.GREEN);

        /*mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFillPaint.setStyle(Paint.Style.STROKE);
        mFillPaint.setStrokeJoin(Paint.Join.ROUND);
        mFillPaint.setStrokeCap(Paint.Cap.ROUND);
        mDefaultPaint.setStrokeWidth(40);
        mFillPaint.setColor(Color.GREEN);*/

        setFocusable(true);
        setFocusableInTouchMode(true);
        setBackgroundColor(Color.WHITE);

        setLayerType(LAYER_TYPE_SOFTWARE, null);
        setSaveEnabled(true);

//      Code for Zoom start
//      detector = new ScaleGestureDetector(getContext(), new ScaleListener());
//      Code for Zoom finish

        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }


    private static float getDegreesFromRadians(float angle) {
        return (float)(angle * 180.0 / Math.PI);
    }


    // Single Touch Code
    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {

        vca = null;
        vcb = null;
        vpa = null;
        vpb = null;

        final int pointerCount = MotionEventCompat.getPointerCount(event);

        switch (MotionEventCompat.getActionMasked(event)) {
        // switch(event.getAction()){
        // switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:
        // case MotionEventCompat.ACTION_POINTER_DOWN:
        {
            if (mFlagDrawing == true) {

        /*      final float xx = event.getX() / mScaleFactor;
                   final float yy = event.getY() / mScaleFactor;
                   mLastTouchX = xx;
                   mLastTouchY = yy;
                   mActivePointerId = event.getPointerId(0);*/

                try {
                    touchManager.update(event);

                    if (touchManager.getPressCount() == 1) {
                        vca = touchManager.getPoint(0);
                        vpa = touchManager.getPreviousPoint(0);
                        position.add(touchManager.moveDelta(0));
                    }
                    else {
                        if (touchManager.getPressCount() == 2) {
                            vca = touchManager.getPoint(0);
                            vpa = touchManager.getPreviousPoint(0);
                            vcb = touchManager.getPoint(1);
                            vpb = touchManager.getPreviousPoint(1);

                            Vector2D current = touchManager.getVector(0, 1);
                            Vector2D previous = touchManager.getPreviousVector(0, 1);
                            float currentDistance = current.getLength();
                            float previousDistance = previous.getLength();

                            if (previousDistance != 0) {
                                scale *= currentDistance / previousDistance;
                            }

                            angle -= Vector2D.getSignedAngleBetween(current, previous);
                        }
                    }

                    invalidate();
                }
                catch(Throwable t) {
                    // So lazy...
                }

                System.out.println("mFlagDrawing: " + mFlagDrawing);
                // Code for Zoom start
                // detector.onTouchEvent(event);
//              mScaleDetector.onTouchEvent(event);
                // Code for Zoom finish
            } else if (mFlagDrawing == false) {
                System.out.println("mFlagDrawing: " + mFlagDrawing);
                for (int p = 0; p < pointerCount; p++) {
                    final int id = MotionEventCompat.getPointerId(event, p);
                    DrawOp current = new DrawOp(mDefaultPaint);
                    current.getPath().moveTo(event.getX(), event.getY());
                    mCurrentOps.put(id, current);
                }
            }
            // mFlagZoom = true;
            // }
        }
            break;

        case MotionEvent.ACTION_MOVE: {

            // for(int p = 0; p < pointerCount; p++){

            if (mFlagDrawing == true) {

    /*             final int pointerIndex = event.findPointerIndex(mActivePointerId);
                   final float xx = event.getX(pointerIndex) / mScaleFactor;
                   final float yy = event.getY(pointerIndex) / mScaleFactor;

                   // Only move if the ScaleGestureDetector isn't processing a gesture.
                   if (!mScaleDetector.isInProgress()) {

                    final float dx = xx - mLastTouchX;
                    final float dy = yy - mLastTouchY;
                    mPosX += dx;
                    mPosY += dy;

                    invalidate();
                   }

                   mLastTouchX = xx;
                   mLastTouchY = yy;*/

                try {
                    touchManager.update(event);

                    if (touchManager.getPressCount() == 1) {
                        vca = touchManager.getPoint(0);
                        vpa = touchManager.getPreviousPoint(0);
                        position.add(touchManager.moveDelta(0));
//                      current.add(touchManager.moveDelta(0));
                    }
                    else {
                        if (touchManager.getPressCount() == 2) {
                            vca = touchManager.getPoint(0);
                            vpa = touchManager.getPreviousPoint(0);
                            vcb = touchManager.getPoint(1);
                            vpb = touchManager.getPreviousPoint(1);

                            Vector2D current = touchManager.getVector(0, 1);
                            Vector2D previous = touchManager.getPreviousVector(0, 1);
                            float currentDistance = current.getLength();
                            float previousDistance = previous.getLength();

                            if (previousDistance != 0) {
                                scale *= currentDistance / previousDistance;
                            }
                            angle -= Vector2D.getSignedAngleBetween(current, previous);
                        }
                    }

                    invalidate();
                }
                catch(Throwable t) {
                    // So lazy...
                }

                System.out.println("mFlagDrawing: " + mFlagDrawing);
                // Code for Zoom start
                // detector.onTouchEvent(event);
//              mScaleDetector.onTouchEvent(event);
                // Code for Zoom finish
            } else if (mFlagDrawing == false) {

                System.out.println("mFlagDrawing: " + mFlagDrawing);
                final int id = MotionEventCompat.getPointerId(event, 0);

                DrawOp current = mCurrentOps.get(id);

                final int historySize = event.getHistorySize();
                for (int h = 0; h < historySize; h++) {
                    x = event.getHistoricalX(h);
                    y = event.getHistoricalY(h);
                    current.getPath().lineTo(x, y);
                }
                x = MotionEventCompat.getX(event, 0);
                y = MotionEventCompat.getY(event, 0);
                current.getPath().lineTo(x, y);

//              position.add(current.getPath());
                // }
            }
        }
            break;

        case MotionEvent.ACTION_UP:
            // case MotionEventCompat.ACTION_POINTER_UP:
            // {
            if (mFlagDrawing == true) {

//               mActivePointerId = INVALID_POINTER_ID;

                try {
                    touchManager.update(event);

                    if (touchManager.getPressCount() == 1) {
                        vca = touchManager.getPoint(0);
                        vpa = touchManager.getPreviousPoint(0);
                        position.add(touchManager.moveDelta(0));
                    }
                    else {
                        if (touchManager.getPressCount() == 2) {
                            vca = touchManager.getPoint(0);
                            vpa = touchManager.getPreviousPoint(0);
                            vcb = touchManager.getPoint(1);
                            vpb = touchManager.getPreviousPoint(1);

                            Vector2D current = touchManager.getVector(0, 1);
                            Vector2D previous = touchManager.getPreviousVector(0, 1);
                            float currentDistance = current.getLength();
                            float previousDistance = previous.getLength();

                            if (previousDistance != 0) {
                                scale *= currentDistance / previousDistance;
                            }

                            angle -= Vector2D.getSignedAngleBetween(current, previous);
                        }
                    }

                    invalidate();
                }
                catch(Throwable t) {
                    // So lazy...
                }

                System.out.println("mFlagDrawing: " + mFlagDrawing);
                // Code for Zoom start
                // detector.onTouchEvent(event);
//              mScaleDetector.onTouchEvent(event);
                // Code for Zoom finish
            } else if (mFlagDrawing == false) {
                System.out.println("mFlagDrawing: " + mFlagDrawing);
                for (int p = 0; p < pointerCount; p++) {
                    final int id = MotionEventCompat.getPointerId(event, p);
                    mDrawOps.push(mCurrentOps.get(id));
                    mCurrentOps.remove(id);
                    // }
                    updateLayer();
                }
            }
            // }
            break;

        case MotionEvent.ACTION_CANCEL: {

            if (mFlagDrawing == true) {

//               mActivePointerId = INVALID_POINTER_ID;

                try {
                    touchManager.update(event);

                    if (touchManager.getPressCount() == 1) {
                        vca = touchManager.getPoint(0);
                        vpa = touchManager.getPreviousPoint(0);
                        position.add(touchManager.moveDelta(0));
                    }
                    else {
                        if (touchManager.getPressCount() == 2) {
                            vca = touchManager.getPoint(0);
                            vpa = touchManager.getPreviousPoint(0);
                            vcb = touchManager.getPoint(1);
                            vpb = touchManager.getPreviousPoint(1);

                            Vector2D current = touchManager.getVector(0, 1);
                            Vector2D previous = touchManager.getPreviousVector(0, 1);
                            float currentDistance = current.getLength();
                            float previousDistance = previous.getLength();

                            if (previousDistance != 0) {
                                scale *= currentDistance / previousDistance;
                            }

                            angle -= Vector2D.getSignedAngleBetween(current, previous);
                        }
                    }

                    invalidate();
                }
                catch(Throwable t) {
                    // So lazy...
                }

                System.out.println("mFlagDrawing: " + mFlagDrawing);
                // Code for Zoom start
                // detector.onTouchEvent(event);
//              mScaleDetector.onTouchEvent(event);
                // Code for Zoom finish
            } else if (mFlagDrawing == false) {
                System.out.println("mFlagDrawing: " + mFlagDrawing);
                for (int p = 0; p < pointerCount; p++) {
                    mCurrentOps
                            .remove(MotionEventCompat.getPointerId(event, p));
                }
            }
            // mFlagZoom = true;
            // }
        }
            break;

        /*case MotionEvent.ACTION_POINTER_UP: {   

               final int pointerIndex = (event.getAction() &    MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
               final int pointerId = event.getPointerId(pointerIndex);
               if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = event.getX(newPointerIndex) / mScaleFactor;
                mLastTouchY = event.getY(newPointerIndex) / mScaleFactor;
                mActivePointerId = event.getPointerId(newPointerIndex);
               }
               break;
              }*/
        default:
            return false;
        }

        invalidate();

        return true;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
        /*mLayerBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mLayerCanvas.setBitmap(mLayerBitmap);*/

        if(mLayerBitmap == null){
             mLayerBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            }else{
                Bitmap temporary = Bitmap.createScaledBitmap(mLayerBitmap, w, h, true);
                mLayerBitmap = temporary;
            }
         mLayerCanvas = new Canvas(mLayerBitmap);

//       mLayerCanvas.rotate(90);
        /* matrix.setTranslate(1.5f,1.5f);
         matrix.postRotate(90, 2.5f, 2.5f);*/

//       updateLayer();


 /*       //Reset the width and height. Will draw bitmap and change
        containerWidth = w;
        containerHeight = h;

        if(mLayerBitmap != null) {
            int imgHeight = mLayerBitmap.getHeight();
            int imgWidth = mLayerBitmap.getWidth();

            float scale;
            int initX = 0;
            int initY = 0;           

            if(defaultScale == DrawingView.DEFAULT_SCALE_FIT_INSIDE) {               
                if(imgWidth > containerWidth) {           
                    scale = (float)containerWidth / imgWidth;           
                    float newHeight = imgHeight * scale;           
                    initY = (containerHeight - (int)newHeight)/2;

                    matrix.setScale(scale, scale);
                    matrix.postTranslate(0, initY);
                }
                else {           
                    scale = (float)containerHeight / imgHeight;
                    float newWidth = imgWidth * scale;
                    initX = (containerWidth - (int)newWidth)/2;

                    matrix.setScale(scale, scale);
                    matrix.postTranslate(initX, 0);
                }

                curX = initX;
                curY = initY;

                currentScale = scale;
                minScale = scale;
            }
            else {
                if(imgWidth > containerWidth) {                                   
                    initY = (containerHeight - (int)imgHeight)/2;                   
                    matrix.postTranslate(0, initY);
                }
                else {                               
                    initX = (containerWidth - (int)imgWidth)/2;                   
                    matrix.postTranslate(initX, 0);
                }

                curX = initX;
                curY = initY;

                currentScale = 1.0f;
                minScale = 1.0f;               
            }


            invalidate();           
        }*/

    }

    private void updateLayer() {
        mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
        for (DrawOp drawOp : mDrawOps) {
            if (drawOp != null) {
                drawOp.draw(mLayerCanvas);
            }
        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (isInEditMode()) {
            return;
        }

//      if(mFlagDrawing == true){
        if (!isInitialized) {
            int w = getWidth();
            int h = getHeight();
            position.set(w / 2, h / 2);
            isInitialized = true;
        }

        mWidth = mLayerBitmap.getWidth();
        mHeight = mLayerBitmap.getHeight();
//      Code for Zoom start
/*      canvas.save();
        canvas.scale(mScaleFactor, mScaleFactor, focusX, focusY);
        canvas.translate(mPosX, mPosY);*/
//      canvas.scale(scaleFactor, scaleFactor);

        /*canvas.scale(mScaleFactor, mScaleFactor, super.getWidth() * 0.5f,
                    super.getHeight() * 0.5f);*/

//      Code for Zoom finish
//      canvas.save();
        transform.reset();
        transform.postTranslate(-mWidth / 2.0f, -mHeight / 2.0f);
//      transform.postRotate(getDegreesFromRadians(angle));
        transform.postScale(scale, scale);
        transform.postTranslate(position.getX(), position.getY());
        canvas.drawBitmap(mLayerBitmap, transform, null);
//      }
//      else if(mFlagDrawing == false){
//      canvas.drawBitmap(mLayerBitmap, 0, 0, null);
        for (int i = 0; i < mCurrentOps.size(); i++) {
            DrawOp current = mCurrentOps.valueAt(i);
            if (current != null) {
                current.draw(canvas);
            }
        }
//      }
//      Code for Zoom
//      canvas.restore();

    }

    public void operationClear() {
        mDrawOps.clear();
        mUndoOps.clear();
        mCurrentOps.clear();
        updateLayer();
    }

    public void operationUndo() {
        if (mDrawOps.size() > 0) {
            mUndoOps.push(mDrawOps.pop());
            updateLayer();
        }
    }

    public void operationRedo() {
        if (mUndoOps.size() > 0) {
            mDrawOps.push(mUndoOps.pop());
            updateLayer();
        }
    }

    public void setPaintStrokeWidth(float widthPx) {
        mDefaultPaint.setStrokeWidth(widthPx);
    }

    public void setPaintOpacity(int percent) {
        int alphaValue = (int) Math.round(percent * (255.0 / 100.0));
        mDefaultPaint.setColor(combineAlpha(mDefaultPaint.getColor(),
                alphaValue));
    }

    public void setPaintColor(String color) {
        mDefaultPaint.setColor(combineAlpha(Color.parseColor(color), mDefaultPaint.getAlpha()));
    }

    public void setPaintColor(int color) {
        mDefaultPaint.setColor(combineAlpha(color, mDefaultPaint.getAlpha()));
    }

    public void setPaintMaskFilter(MaskFilter filter) {
        mDefaultPaint.setMaskFilter(filter);
    }

    public void setPaintShader(BitmapShader shader) {
        mDefaultPaint.setShader(shader);
    }

    public void setPaintColorFilter(ColorFilter colorFilter) {
        mDefaultPaint.setColorFilter(colorFilter);
    }

    private static int combineAlpha(int color, int alpha) {
        return (color & 0x00FFFFFF) | ((alpha & 0xFF) << 24);
    }

    private static class DrawOp {
        private float x,y;
        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private final Path mPath = new Path();

        public DrawOp(Paint paint) {
            reset(paint);
        }

        /*public void add(Vector2D moveDelta) {
            // TODO Auto-generated method stub
            this.x += moveDelta.getX();
            this.y += moveDelta.getY();

        }*/

        void reset(Paint paint) {
            mPath.reset();
            update(paint);
        }

        void update(Paint paint) {
            mPaint.set(paint);
        }

        void draw(Canvas canvas) {
            canvas.drawPath(mPath, mPaint);
        }

        public Path getPath() {
            return mPath;
        }

    /*  public DrawOp add(DrawOp value) {
            this.x += value.getX();
            this.y += value.getY();
            return this;
        }*/

        /*public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }*/

    }
    public void fillShapeColor(){



    }


//  Code for Zoom
/*  private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override

        public boolean onScale(ScaleGestureDetector detector) {

        scaleFactor *= detector.getScaleFactor();

        scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM));

        invalidate();

        return true;

        }

        }*/

     private class ScaleListener extends
       ScaleGestureDetector.SimpleOnScaleGestureListener {
      @Override
      public boolean onScaleBegin(ScaleGestureDetector detector) {

       // float x = detector.getFocusX();
       // float y = detector.getFocusY();

       lastFocusX = -1;
       lastFocusY = -1;

       return true;
      }

      @Override
      public boolean onScale(ScaleGestureDetector detector) {
       mScaleFactor *= detector.getScaleFactor();

       focusX = detector.getFocusX();
       focusY = detector.getFocusY();


       if (lastFocusX == -1)
        lastFocusX = focusX;
       if (lastFocusY == -1)
        lastFocusY = focusY;

       mPosX += (focusX - lastFocusX);
       mPosY += (focusY - lastFocusY);
       Log.v("Hi Zoom", "Factor:"  + mScaleFactor);
       // Don't let the object get too small or too large.
       mScaleFactor = Math.max(0.5f, Math.min(mScaleFactor, 2.0f));

       lastFocusX = focusX;
       lastFocusY = focusY;

       invalidate();
       return true;
      }
     }


/*    @Override
    public Parcelable onSaveInstanceState() 
    {
        System.out.println("save instance");
        Bundle bundle = new Bundle();
        bundle.putParcelable(EXTRA_STATE, super.onSaveInstanceState());  
        bundle.putParcelableArrayList(EXTRA_EVENT_LIST, eventList);

    return bundle;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) 
    {
        if (state instanceof Bundle) 
        {
            Bundle bundle = (Bundle) state;
            super.onRestoreInstanceState(bundle.getParcelable(EXTRA_STATE));
            eventList = bundle.getParcelableArrayList(EXTRA_EVENT_LIST);
            if (eventList == null) {
               eventList = new ArrayList<MotionEvent>(100); 
            }
            for (MotionEvent event : eventList) {
//               performTouchEvent(event);
            }               
            return;
        }
        super.onRestoreInstanceState(state);
    }*/

    public void setDrawingFlag(boolean flag) {
//      System.out.println("Before Set mFlag " + mFlagDrawing);
        this.mFlagDrawing = flag;
//      System.out.println("After Set mFlag " + mFlagDrawing);
    }


    public void moveCanvas(float x, float y) {
        float dx = x - mLastTouchX;
        float dy = y - mLastTouchY;
        // Adjust for zoom factor. Otherwise, the user's finger moving 10 pixels
        // at 200% zoom causes the image to slide 20 pixels instead of perfectly
        // following the user's touch
        dx /= (mScaleFactor * 2);
        dy /= (mScaleFactor * 2);

        mPosX += dx;
        mPosY += dy;

        // Log.v(TAG, "moving by " + dx + "," + dy + " mScaleFactor: " +
        // mScaleFactor);
    }
}
公共类DrawingView扩展视图{
//缩放代码16-6-2015下午4:12
私有静态final int无效\u指针\u ID=-1;
公共位图MMY字符;
私人浮动mPosX;
私家车;
私有浮动mLastTouchX;
私密的浮躁和敏感;
private int mActivePointerId=无效的\u指针\u ID;
查看当前视图;
专用scalegestruedetector mScaleDetector;
私人浮动mScaleFactor=1.f;
私人浮动焦点;
私人浮动焦点;
私有浮点lastFocusX=-1;
private float lastFocusY=-1;
静态最终int IMG_宽度=640;
静态最终内模高度=480;
静态最终整型图像_X_POS=560;
静态最终整数图像_Y_POS=20;
漂浮物;
浮动sx;
公共静态语境;
//   -------------------------------------
//   ...................................
/*私有最终位图;
私有最终整数宽度;
私人最终整数高度*/
私有矩阵变换=新矩阵();
私有向量2D位置=新向量2D();
私人浮动比例=1;
专用浮动角度=0;
私有TouchManager TouchManager=新TouchManager(2);
私有布尔值isInitialized=false;
//调试帮助程序以在两个接触点之间绘制线
私有向量2d vca=null;
私有向量2d vcb=null;
私有向量2D vpa=null;
私有向量2d vpb=null;
国际宽度;
整数mHeight;
//      ...............................
私人最终涂料mDefaultPaint;
私人涂料;
浮动x,y;
私有画布mLayerCanvas=新画布();
私有位图mLayerBitmap;
私有堆栈mDrawOps=新堆栈();
私有堆栈mUndoOps=新堆栈();
专用SparseArray mCurrentOps=新SparseArray(0);
//用于拖放缩放代码初始化
专用静态浮动最小缩放=1f;
私有静态浮动最大缩放=2f;
私有浮点scaleFactor=1.f;
专用静态标度检测器;
布尔图;
私有最终矩阵mMatrix=新矩阵();
int y_old=0,y_new=0;int zoomMode=0;
浮动夹点距离旧=0,夹点距离新=0;
int zoomControllerScale=1;//用于确定缩放比例的新旧收缩距离
//这些矩阵将用于移动和缩放图像
矩阵=新矩阵();
矩阵savedMatrix=新矩阵();
//记住一些关于缩放的事情
PointF start=新的PointF();
PointF mid=新的PointF();
浮动oldDist=1f;
//我们可能处于这三种状态之一
静态最终int NONE=0;
静态最终int PAN=1;
静态最终整数缩放=2;
int模式=无;
私有静态最终字符串TAG=“DebugTag”;
//新代码
私有位图imgBitmap=null;
私人集装箱宽度;
私人集装箱重量;
绘画背景;
//矩阵将用于移动和缩放图像
//矩阵=新矩阵();
//矩阵savedMatrix=新矩阵();
//PointF start=新的PointF();
浮子电流标度;
浮凝乳;
漂浮凝乳;
//我们可能处于这三种状态之一
//静态最终int NONE=0;
//静态最终整数阻力=1;
//静态最终整数缩放=2;
//int模式=无;
//用于制作动画
浮动targetX;
浮动目标;
浮动目标标度;
浮动targetScaleX;
浮动靶标;
浮标变化;
浮动目标;
浮动过渡比率;
浮动松动=0.2f;
布尔isAnimating=false;
浮标阻尼系数=0.5f;
//用于收缩和缩放
//浮动oldDist=1f;
//PointF mid=新的PointF();
私有处理程序mHandler=新处理程序();
浮标;
浮动最大刻度=8.0f;
浮球半径=25.0f;
浮动半径=20.0f;
浮筛密度;
私人手势检测器;
公共静态最终整数默认值\比例\拟合\内部=0;
公共静态最终整数默认值\比例\原始值=1;
私人规模;
私有静态最终字符串EXTRA\u EVENT\u LIST=“EVENT\u LIST”;
私有静态最终字符串EXTRA_STATE=“instance_STATE”;
私有ArrayList事件列表=新ArrayList(100);
公共绘图视图(上下文){
这个(上下文,null,0);
}
公共绘图视图(上下文、属性集属性){
这(上下文,属性,0);
//检测器=新的scalegestruedetector(getContext(),newscaleListener());
}
公共绘图视图(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
mDefaultPaint=新油漆(油漆.防油漆别名标志);
mDefaultPaint.setStyle(Paint.Style.STROKE);
mDefaultPaint.setStrokeJoin(绘制.连接.圆形);
mDefaultPaint.setStrokeCap(油漆盖圆形);
mDefaultPaint.设定行程宽度(40);
mDefaultPaint.setColor(Color.GREEN);
/*mFillPaint=新油漆(油漆.防油漆别名标志);
mFillPaint.setStyle(Paint.Style.STROKE);
mFillPaint.setStrokeJoin(Paint.Join.ROUND);
mFillPaint.setStrokeCap(油漆盖圆形);
mDefaultPaint.设定行程宽度(40);
mFillPaint.setColor(颜色.绿色)*/
设置聚焦(真);
setFocusableInTouchMode(真);
setBackgroundColor(颜色:白色);
setLayerType(层类型软件,空);
setSaveEnabled(真);
//缩放开始代码
//检测器=新的scalegestruedetector(getContext(),newscaleListener());
//代码
public void resetZoom() {
        mPanX = mPanY = 0;
        final Matrix m = new Matrix();
        m.postScale(1f / DENSITY, 1f / DENSITY);
        setZoom(m);
        invalidate();
    }

    public void setZoomPosNoInval(float x, float y) {
        mPanX = x;
        mPanY = y;
    }

    public void setZoomPos(float x, float y) {
        setZoomPosNoInval(x, y);
        invalidate();
    }

    public void setZoomPosNoInval(float[] pos) {
        setZoomPosNoInval(pos[0], pos[1]);
    }

    public void setZoomPos(float[] pos) {
        setZoomPosNoInval(pos);
        invalidate();
    }

    public float[] getZoomPos(float[] pos) {
        if (pos == null)
            pos = new float[2];
        pos[0] = mPanX;
        pos[1] = mPanY;
        return pos;
    }

    public float getZoomPosX() {
        return mPanX;
    }

    public float getZoomPosY() {
        return mPanY;
    }

    public Matrix getZoom() {
        return mZoomMatrix;
    }

    public Matrix getZoomInv() {
        return mZoomMatrixInv;
    }

    public void setZoom(Matrix m) {
        mZoomMatrix.set(m);
        mZoomMatrix.invert(mZoomMatrixInv);
    }