2017-10-16 1 views
0

J'ai ce qui suit qui me permet de zoomer et dézoomer indéfiniment, mais j'essaie de définir une valeur min et max pour le zoom afin que la mise en page ne soit pas trop grande ou trop petit. J'ai essayé d'utiliser mais je ne comprends pas où placer ceci dans le code.Comment vous pouvez avoir des valeurs min et max pour zoomer dans la mise en page

private static final float MIN_ZOOM = 1.0f; 
private static final float MAX_ZOOM = //set Maximum zooming level 
float scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM)); 

public class ZoomableView extends RelativeLayout { 

    // States. 
    private static final byte NONE = 0; 
    private static final byte DRAG = 1; 
    private static final byte ZOOM = 2; 

    private byte mode = NONE; 

    // Matrices used to move and zoom image. 
    private Matrix matrix = new Matrix(); 
    private Matrix matrixInverse = new Matrix(); 
    private Matrix savedMatrix = new Matrix(); 

    // Parameters for zooming. 
    private PointF start = new PointF(); 
    private PointF mid = new PointF(); 
    private float oldDist = 1f; 
    private float[] lastEvent = null; 
    private long lastDownTime = 0l; 

    private float[] mDispatchTouchEventWorkingArray = new float[2]; 
    private float[] mOnTouchEventWorkingArray = new float[2]; 


    @Override 
    public boolean dispatchTouchEvent(MotionEvent ev) { 
     mDispatchTouchEventWorkingArray[0] = ev.getX(); 
     mDispatchTouchEventWorkingArray[1] = ev.getY(); 
     mDispatchTouchEventWorkingArray = screenPointsToScaledPoints(mDispatchTouchEventWorkingArray); 
     ev.setLocation(mDispatchTouchEventWorkingArray[0], mDispatchTouchEventWorkingArray[1]); 
     return super.dispatchTouchEvent(ev); 
    } 

    public ZoomableView(Context context) { 
     super(context); 
     init(context); 
    } 

    public ZoomableView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context); 
    } 

    public ZoomableView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(context); 
    } 


    private void init(Context context) { 

    } 


    /** 
    * Determine the space between the first two fingers 
    */ 
    private float spacing(MotionEvent event) { 
     float x = event.getX(0) - event.getX(1); 
     float y = event.getY(0) - event.getY(1); 
     return (float) Math.sqrt(x * x + y * y); 
    } 

    /** 
    * Calculate the mid point of the first two fingers 
    */ 
    private void midPoint(PointF point, MotionEvent event) { 
     float x = event.getX(0) + event.getX(1); 
     float y = event.getY(0) + event.getY(1); 
     point.set(x/2, y/2); 
    } 

    private float[] scaledPointsToScreenPoints(float[] a) { 
     matrix.mapPoints(a); 
     return a; 
    } 

    private float[] screenPointsToScaledPoints(float[] a) { 
     matrixInverse.mapPoints(a); 
     return a; 
    } 


    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     int childCount = getChildCount(); 
     for (int i = 0; i < childCount; i++) { 
      View child = getChildAt(i); 
      if (child.getVisibility() != GONE) { 
       child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight()); 
      } 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     int childCount = getChildCount(); 
     for (int i = 0; i < childCount; i++) { 
      View child = getChildAt(i); 
      if (child.getVisibility() != GONE) { 
       measureChild(child, widthMeasureSpec, heightMeasureSpec); 
      } 
     } 
    } 

    @Override 
    protected void dispatchDraw(Canvas canvas) { 
     float[] values = new float[9]; 
     matrix.getValues(values); 
     canvas.save(); 
     canvas.translate(values[Matrix.MTRANS_X], values[Matrix.MTRANS_Y]); 
     canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]); 
     super.dispatchDraw(canvas); 
     canvas.restore(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     // handle touch events here 
     mOnTouchEventWorkingArray[0] = event.getX(); 
     mOnTouchEventWorkingArray[1] = event.getY(); 

     mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray); 

     event.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]); 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 
      case MotionEvent.ACTION_DOWN: 
       savedMatrix.set(matrix); 
       mode = DRAG; 
       lastEvent = null; 
       long downTime = event.getDownTime(); 
       if (downTime - lastDownTime < 300l) { 
        float density = getResources().getDisplayMetrics().density; 
        if (Math.max(Math.abs(start.x - event.getX()), Math.abs(start.y - event.getY())) < 40.f * density) { 
         savedMatrix.set(matrix); 
         mid.set(event.getX(), event.getY()); 
         mode = ZOOM; 
         lastEvent = new float[4]; 
         lastEvent[0] = lastEvent[1] = event.getX(); 
         lastEvent[2] = lastEvent[3] = event.getY(); 
        } 
        lastDownTime = 0l; 
       } else { 
        lastDownTime = downTime; 
       } 
       start.set(event.getX(), event.getY()); 
       break; 
      case MotionEvent.ACTION_POINTER_DOWN: 
       oldDist = spacing(event); 
       if (oldDist > 10f) { 
        savedMatrix.set(matrix); 
        midPoint(mid, event); 
        mode = ZOOM; 
       } 
       lastEvent = new float[4]; 
       lastEvent[0] = event.getX(0); 
       lastEvent[1] = event.getX(1); 
       lastEvent[2] = event.getY(0); 
       lastEvent[3] = event.getY(1); 
       break; 
      case MotionEvent.ACTION_UP: 
      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       lastEvent = null; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       final float density = getResources().getDisplayMetrics().density; 
       if (mode == DRAG) { 
        matrix.set(savedMatrix); 
        float dx = event.getX() - start.x; 
        float dy = event.getY() - start.y; 
        matrix.postTranslate(dx, dy); 
        matrix.invert(matrixInverse); 
        if (Math.max(Math.abs(start.x - event.getX()), Math.abs(start.y - event.getY())) > 20.f * density) { 
         lastDownTime = 0l; 
        } 
       } else if (mode == ZOOM) { 
        if (event.getPointerCount() > 1) { 
         float newDist = spacing(event); 
         if (newDist > 10f * density) { 
          matrix.set(savedMatrix); 
          float scale = (newDist/oldDist); 
          matrix.postScale(scale, scale, mid.x, mid.y); 
          matrix.invert(matrixInverse); 
         } 
        } else { 
         matrix.set(savedMatrix); 
         float scale = event.getY()/start.y; 
         matrix.postScale(scale, scale, mid.x, mid.y); 
         matrix.invert(matrixInverse); 
        } 
       } 
       break; 
     } 

     invalidate(); 
     return true; 
    } 


} 

Répondre

0

Vous devez faire une classe étendue RelativeLayout, là, vous pouvez le mettre en redéfinissant la getMaxZoomLevel() et getMinZoomLevel(), comme ceci:

public class ZoomableView extends RelativeLayout { 

@Override 
public int getMaxZoomLevel() { 
    return 22; 
} 

@Override 
public int getMinZoomLevel() { 
    return 12; 
} 

} 
+0

Salut Feras, merci pour votre commentaire. Je comprends comment mettre en œuvre ce que vous m'avez dit, mais je ne sais pas exactement où iraient les valeurs 22 et 12. Dois-je créer une instruction if pour les valeurs min et max? - Si oui, comment dirais-je si le maximum est 22, arrêter de zoomer? – Moo