2012-04-19 86 views
0

霍伊, 缩放ImageView的时候,这是我的课:如何定义最大和最小缩放LVL,通过矩阵

public class MultiTouchHandler implements OnTouchListener { 
private static final int NONE = 0; 
private static final int DRAG = 1; 
private static final int ZOOM = 2; 
private static final float MIN_ZOOM = 0.5f; 
private static final float MAX_ZOOM = 2.0f; 

private int mode = NONE; 
private float oldDist; 
private PointF mid; 
private PointF start; 
private Matrix matrix; 
private Matrix savedMatrix; 
private ImageView reticle; 
private int imageWidth; 
private int imageHeight; 
private float[] values; 
private boolean isTouched; 
private float width; 
private float height; 
private float scale; 

public MultiTouchHandler(ImageView v) { 
    reticle = v; 
    v.setOnTouchListener(this); 
    mid = new PointF(); 
    start = new PointF(); 

    imageWidth = v.getDrawable().getIntrinsicWidth(); 
    imageHeight = v.getDrawable().getIntrinsicHeight(); 

    matrix = new Matrix(); 
    savedMatrix = new Matrix(); 
    values = new float[9]; 

} 

public boolean onTouch(View v, MotionEvent event) { 
    synchronized (this) { 
     if(reticle.getScaleType() != ScaleType.MATRIX){ 
      reticle.setScaleType(ScaleType.MATRIX); 
      matrix.postTranslate(reticle.getWidth()/2 - imageWidth/2, reticle.getHeight()/2 - imageHeight/2); 
      reticle.setImageMatrix(matrix); 
     } 

     matrix.getValues(values); 
     width = values[0]*imageWidth; 
     height = values[4]*imageHeight; 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 
      case MotionEvent.ACTION_DOWN: 
       savedMatrix.set(matrix); 
       if(event.getX() > values[2] && event.getX() < values[2] + width && 
        event.getY() > values[5] && event.getY() < values[5] + height){ 
        start.set(event.getX(), event.getY()); 
        isTouched = true; 
       } 
       mode = DRAG; 
       break; 

      case MotionEvent.ACTION_POINTER_DOWN: 
       oldDist = spacing(event); 
       if (oldDist > 10f) { 
        savedMatrix.set(matrix); 
        midPoint(mid, event); 
        mode = ZOOM; 
       } 
       break; 

      case MotionEvent.ACTION_UP: 
      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       isTouched = false; 
       break; 

      case MotionEvent.ACTION_MOVE: 
       if (mode == DRAG && isTouched) { 
       matrix.set(savedMatrix); 
       matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); 
       } 
       else if (mode == ZOOM) { 
        float newDist = spacing(event); 
        if (newDist > 10f) { 
        matrix.set(savedMatrix); 
        scale = newDist/oldDist; 

        Log.v("scale", "" + scale); 

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

        Log.v("new scale", "" + scale); 

        matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
       } 
       break; 
     } 
     reticle.setImageMatrix(matrix); 
     return true; 
    } 
} 

private float spacing(MotionEvent event) { 
     float x = event.getX(0) - event.getX(1); 
     float y = event.getY(0) - event.getY(1); 
     return FloatMath.sqrt(x * x + y * y); 
} 

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

}

的问题是,它仅适用于那些实际捏/缩放,而不是全球范围......我试图挽救全球规模,每次我扩大我的实际规模乘以全球规模,但这是useles ...它接缝,从矩阵得到的规模是全球的,但它不像一个。我究竟做错了什么?任何人都可以帮忙吗?感谢您的回答。

+0

您是否删除了旧的问题?如果我没记错的话,你之前问过这个问题如果您删除了旧问题,请注意,这不是这个社区的工作方式! – WarrenFaith 2012-04-19 10:09:04

+0

是的,我做了......我以为我解决了它,但不幸的是我没有,所以我认为如果我打破了一些规则,开始有关该主题的更多信息的新问题会更好,我很抱歉 – Belovoj 2012-04-19 11:04:50

回答

0

所以这是我如何解决它...它是不是很优雅,但它的工作原理

else if (mode == ZOOM) { 
        float newDist = spacing(event); 
        if (newDist > 10f) { 
        matrix.set(savedMatrix); 
        matrix.getValues(values); 

        if(values[0] < MAX_ZOOM && values[0] > MIN_ZOOM){ 
         scale = newDist/oldDist; 
         scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));       
         matrix.postScale(scale, scale, mid.x, mid.y); 

         reticle.setImageMatrix(matrix); 
        } else if(values[0] >= MAX_ZOOM){ 
         newScale = newDist/oldDist; 
         if(newScale < scale){ 
          scale = newScale; 
          scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));       
          matrix.postScale(scale, scale, mid.x, mid.y); 

          reticle.setImageMatrix(matrix); 
         } 
        } else if(values[0] <= MIN_ZOOM){ 
         newScale = newDist/oldDist; 
         if(newScale > scale){ 
          scale = newScale; 
          scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));       
          matrix.postScale(scale, scale, mid.x, mid.y); 

          reticle.setImageMatrix(matrix); 
         } 
        } 
        } 
       } 

这是代码的唯一的和平,我编辑

1

为什么没有人使用ScaleGestureDetector为这种事情?我正在研究一些非常相似的东西,并且使用了一个扩展ScaleGestureDetector.SimpleOnScaleListener的小助手类。

class ScaleListener extends 
    ScaleGestureDetector.SimpleOnScaleGestureListener { 

    float scaleFactor; 
    Matrix matrix; 

    public ScaleListener(){ 
     super(); 
     scaleFactor = 1.0f; 
     matrix = new Matrix(); 
    } 

    public boolean onScale(ScaleGestureDetector detector){ 
     //updating the scalefactor after the current gesture 
     scaleFactor *= detector.getScaleFactor(); 

     //making sure the scale is within the limits 
     scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM)); 

     //applying the scale via a matrix to the imageview 
     matrix.setScale(scaleFactor, scaleFactor); 
     imageview.setImageMatrix(matrix) 
    } 
} 

我对你关于全局尺度的问题有点困惑,但是matrix/scaleFactor包含了imageview的全局尺度。希望这有助于,尽管它有点晚!

相关问题