Question

I'm building an app that uses the pinch zoom and drag. The problem is that for now I can drag the picture out of it bounds. I wanted to know how can I use drag and make sure the image stays on the screen at the same time.

Here is my code :

public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView)v;
      //handle touch events here.
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
       case MotionEvent.ACTION_DOWN:
          savedMatrix.set(matrix);
          start.set(event.getX(), event.getY());
          Log.d(TAG, "mode=DRAG" );
          mode = DRAG;
          break;
       case MotionEvent.ACTION_POINTER_DOWN:
           oldDist = spacing(event);
           Log.d(TAG, "oldDist=" + oldDist);
           if (oldDist > 10f) {
              savedMatrix.set(matrix);
              midPoint(mid, event);
              mode = ZOOM;
              Log.d(TAG, "mode=ZOOM" );
           }
           break;
       case MotionEvent.ACTION_UP:
       case MotionEvent.ACTION_POINTER_UP:
          mode = NONE;
          Log.d(TAG, "mode=NONE" );
          break;
       case MotionEvent.ACTION_MOVE:
          if (mode == DRAG) {
             matrix.set(savedMatrix);
             matrix.postTranslate(event.getX() - start.x,
             event.getY() - start.y);
          }
          else if (mode == ZOOM) {
              Float newDist = spacing(event);
              Log.d(TAG, "newDist=" + newDist);
              if (newDist > 10f) {
                 matrix.set(savedMatrix);
                 Float scale = newDist / oldDist;

                 Matrix temp = new Matrix();
                 temp.set(matrix);
                 temp.postScale(scale, scale, mid.x, mid.y);
                 float[] f = new float[9];
                 temp.getValues(f);
                 Float xScale = f[0];
                 if(xScale >= 1 && xScale <= 10){
                     matrix.postScale(scale, scale, mid.x, mid.y);
                     savedMatrixZoom.set(matrix);
                 }else{
                     matrix.set(savedMatrixZoom);

              }

              }
          break;
          }       
     } //perform the transformation.

     view.setImageMatrix(matrix);
     return true; // indicate event was handled  
}
Was it helpful?

Solution

Why not grab the dimensions of the screen and check the MotionEvent coordinates are within these before updating your matrix?

Something like..

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenHight = displaymetrics.heightPixels;
int screenWidth = displaymetrics.widthPixels;

   ...
   case MotionEvent.ACTION_MOVE:

      if (mode == DRAG) {

         int newX = event.getX() - start.x;
         int newY = event.getY() - start.y;
         if ( (newX <= 0 || newX >= screenWidth) ||
              (newY <= 0 || newY >= screenHeight) )
             break;

         matrix.set(savedMatrix);
         matrix.postTranslate(newX, newY);
      }
   ...

OTHER TIPS

public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int sH = displaymetrics.heightPixels;
        int sW = displaymetrics.widthPixels;
        float dx, dy, newX, newY;

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                dx = event.getRawX() - v.getX();
                dy = event.getRawY() - v.getY();
                break;

            case MotionEvent.ACTION_MOVE:
                newX = event.getRawX() - dx;
                newY = event.getRawY() - dy;

                if ((newX <= 0 || newX >= sW-v.getWidth()) || (newY <= 0 || newY >= sH-v.getHeight()))
                    break;

                v.setX(newX);
                v.setY(newY);
                break;   

            default:
                break;
        }

        return true;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top