2012-04-19 11 views
0

によってホイ、 をImageViewのスケーリング時に、これは私のクラスで、maxとminは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 ...それは行列から取得する尺度がグローバルしかし、それは1のように動作していません。私は間違って何をしていますか?誰でも助けてくれますか?答えをありがとう。

+0

古い質問を削除しましたか?私が正しく覚えていれば、これは前に尋ねましたあなたが古い質問を削除した場合、これはこのコミュニティの仕組みではないことにご注意ください! – WarrenFaith

+0

はい、私は...私はそれを解決したと思ったが、残念ながら私はしなかったので、私はいくつかのルールを破った場合、私はそれがトピックについての詳細で新しい質問を開始する方が良いと思った、 – Belovoj

答えて

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

私は地球規模についての質問で少し混乱しているが、マトリックス/ scaleFactorをImageViewのは、グローバルな規模が含まれています。少し遅れても、これが助けてくれることを願っています!