2012-04-19 123 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的全局尺度。希望這有助於,儘管它有點晚!

相關問題