2014-10-19 101 views
1

问候来自保加利亚:)的Android用两个手指缩放 - onTouch和setScaleX,setScaleY

我解决有关使用setScaleX和setScaleY缩放一个Android编程任务。问题出现在我缩放并移除手指后。因此,我将手指移开并重新放在屏幕上,然后重新调整ImageView。我不想那样。

@Override 
     public boolean onTouch(View v, MotionEvent event) { 
      if (event.getPointerCount() == 1) { 

      } else if (event.getPointerCount() == 2) { 

       if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN 
         || event.getActionMasked() == MotionEvent.ACTION_DOWN) { 
        float diff_y = event.getY(0) - event.getY(1); 
        float diff_x = event.getX(0) - event.getX(1); 
        history_angle = (float) Math.toDegrees(Math.atan2(
          diff_y, diff_x)); 

         history_dist = FloatMath.sqrt(diff_x * diff_x 
           + diff_y * diff_y); 

       } else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { 

        float diff_y = event.getY(0) - event.getY(1); 
        float diff_x = event.getX(0) - event.getX(1); 
        float angle = (float) Math.toDegrees(Math.atan2(diff_y, 
          diff_x)); 
        float dist_angle = angle - history_angle; 
        img.setRotation(img.getRotation() + dist_angle); 
        history_angle = angle; 

        float distCurrent = FloatMath.sqrt(diff_x * diff_x 
          + diff_y * diff_y); 

        float curScale = distCurrent/history_dist; 

        img.setScaleX(curScale); 
        img.setScaleY(curScale); 

       } 
      } 
      return true; 
     } 
    }); 

请指教!

谢谢您的帮助提前祝你愉快的一天:)

P.S:在分配我必须使用setScaleX和setScaleY和距离之间的手指:)

回答

2

你应该使用矩阵!

这里的代码,我希望下面的顺序将帮助您:

公共类TouchImageView扩展的ImageView {

private static final String TAG = "Touch"; 
// These matrices will be used to move and zoom image 
Matrix matrix = new Matrix(); 
Matrix savedMatrix = new Matrix(); 

// We can be in one of these 3 states 
static final int NONE = 0; 
static final int DRAG = 1; 
static final int ZOOM = 2; 
int mode = NONE; 

// Remember some things for zooming 
PointF start = new PointF(); 
PointF mid = new PointF(); 
float oldDist = 1f; 

Context context; 


public TouchImageView(Context context) { 
    super(context); 
    super.setClickable(true); 
    this.context = context; 

    matrix.setTranslate(1f, 1f); 
    setImageMatrix(matrix); 
    setScaleType(ScaleType.MATRIX); 

    setOnTouchListener(new OnTouchListener() { 

     @Override 
     public boolean onTouch(View v, MotionEvent rawEvent) { 
      WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent); 

      // Dump touch event to log 
      if (Viewer.isDebug == true){ 
       dumpEvent(event); 
      } 

      // 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: 
       int xDiff = (int) Math.abs(event.getX() - start.x); 
       int yDiff = (int) Math.abs(event.getY() - start.y); 
       if (xDiff < 8 && yDiff < 8){ 
        performClick(); 
       } 
      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.postScale(scale, scale, mid.x, mid.y); 
        } 
       } 
       break; 
      } 

      setImageMatrix(matrix); 
      return true; // indicate event was handled 
     } 

    }); 
} 


public void setImage(Bitmap bm, int displayWidth, int displayHeight) { 
    super.setImageBitmap(bm); 

    //Fit to screen. 
    float scale; 
    if ((displayHeight/bm.getHeight()) >= (displayWidth/bm.getWidth())){ 
     scale = (float)displayWidth/(float)bm.getWidth(); 
    } else { 
     scale = (float)displayHeight/(float)bm.getHeight(); 
    } 

    savedMatrix.set(matrix); 
    matrix.set(savedMatrix); 
    matrix.postScale(scale, scale, mid.x, mid.y); 
    setImageMatrix(matrix); 


    // Center the image 
    float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ; 
    float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth()); 

    redundantYSpace /= (float)2; 
    redundantXSpace /= (float)2; 


    savedMatrix.set(matrix); 
    matrix.set(savedMatrix); 
    matrix.postTranslate(redundantXSpace, redundantYSpace); 
    setImageMatrix(matrix); 
} 


/** Show an event in the LogCat view, for debugging */ 
private void dumpEvent(WrapMotionEvent event) { 
    // ... 
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", 
     "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; 
    StringBuilder sb = new StringBuilder(); 
    int action = event.getAction(); 
    int actionCode = action & MotionEvent.ACTION_MASK; 
    sb.append("event ACTION_").append(names[actionCode]); 
    if (actionCode == MotionEvent.ACTION_POINTER_DOWN 
      || actionCode == MotionEvent.ACTION_POINTER_UP) { 
     sb.append("(pid ").append(
       action >> MotionEvent.ACTION_POINTER_ID_SHIFT); 
     sb.append(")"); 
    } 
    sb.append("["); 
    for (int i = 0; i < event.getPointerCount(); i++) { 
     sb.append("#").append(i); 
     sb.append("(pid ").append(event.getPointerId(i)); 
     sb.append(")=").append((int) event.getX(i)); 
     sb.append(",").append((int) event.getY(i)); 
     if (i + 1 < event.getPointerCount()) 
     sb.append(";"); 
    } 
    sb.append("]"); 
    Log.d(TAG, sb.toString()); 
} 

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

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

}