2014-09-10 22 views
5

tôi cần phải thêm các tính năng sau đây trong ứng dụng của tôiquy mô Android zoom zoomout bitmap trên vải

Tôi có để hiển thị Bitmap vào Canvas

Sau đó, người dùng có thể phóng to và thu nhỏ bitmap vào Canvas

thế nào để làm cho nó có thể? Tôi chỉ cần nó trong Canvas không ImageView

Tất cả các câu trả lời là không hữu ích nhiều cho tôi .. vì vậy tôi nghĩ rằng để cập nhật Câu hỏi của tôi

Về cơ bản tôi cần 2 nút đơn giản và một canvas ...

trên nút đầu tiên nhấp vào hình ảnh trên canvas có thể xoay/phóng to và thu phóng và khi nhấp vào nút thứ hai, nó phải hiển thị hình thu nhỏ hoặc thu nhỏ do người dùng tạo và sau đó người dùng không thể phóng to hoặc thu nhỏ canvas

+0

Bạn có thể sử dụng ScaleGestureDetector trong chế độ xem canvas của mình. –

+0

xem câu trả lời của tôi ở đây: http://stackoverflow.com/questions/21633545/android-imageview-scaling-and-translating-issue – pskink

Trả lời

6

Nếu bạn phóng to và thu nhỏ bitmap trong canvas e mã dưới đây fore rằng

Thêm mã của bạn trong hoạt động của bạn

MyView myView = new MyView(this); 
    setContentView(myView); 

và dưới tầm nhìn của bạn.

public class MyView extends View { 
private Drawable image; 
private ScaleGestureDetector scaleDetector; 
private float scaleFactor = 1.f; 

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

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

public MyView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context); 
} 

private void init(Context ctx) { 
    image = getResources().getDrawable(R.drawable.ic_launcher); 
    image.setBounds(0, 0, image.getIntrinsicWidth(), 
      image.getIntrinsicHeight()); 
    scaleDetector = new ScaleGestureDetector(ctx, new ScaleListener()); 
} 


@Override 
protected void onDraw(Canvas canvas) { 
    canvas.save(); 
    canvas.scale(scaleFactor, scaleFactor); 
    image.draw(canvas); 
    canvas.restore(); 

}; 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    scaleDetector.onTouchEvent(ev); 
    return true; 
} 

private class ScaleListener extends 
     ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     scaleFactor *= detector.getScaleFactor(); 
     scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 10.0f)); 
     invalidate(); 
     return true; 
    } 
} 
} 
+0

Nếu tôi có nhiều bitmap trên canvas, đây là tỷ lệ của cả hai, không phải là duy nhất – Donato

+0

Tôi cần một giải pháp để chia tỷ lệ bitmap đã bị chèn ép, không phải toàn bộ canvas. – Donato

2

Bạn có thể sử dụng lớp chế độ xem tùy chỉnh này, nó cung cấp kéo cùng với hiệu ứng thu phóng. Tôi không phải là tác giả ban đầu của lớp học này, tôi đã sao chép nó từ số tutorial này. Bạn có thể đi qua tutorial pages nếu bạn muốn xem từng bước làm thế nào để đạt được hiệu ứng này.

public class ZoomView extends View { 

     //These two constants specify the minimum and maximum zoom 
     private static float MIN_ZOOM = 1f; 
     private static float MAX_ZOOM = 5f; 

     private float scaleFactor = 1.f; 
     private ScaleGestureDetector detector; 

     //These constants specify the mode that we're in 
     private static int NONE = 0; 
     private static int DRAG = 1; 
     private static int ZOOM = 2; 

     private int mode; 

     //These two variables keep track of the X and Y coordinate of the finger when it first 
     //touches the screen 
     private float startX = 0f; 
     private float startY = 0f; 

     //These two variables keep track of the amount we need to translate the canvas along the X 
     //and the Y coordinate 
     private float translateX = 0f; 
     private float translateY = 0f; 

     //These two variables keep track of the amount we translated the X and Y coordinates, the last time we 
     //panned. 
     private float previousTranslateX = 0f; 
     private float previousTranslateY = 0f;  

     public ZoomView(Context context) { 
      super(context); 
      detector = new ScaleGestureDetector(getContext(), new ScaleListener()); 
     } 

     @Override 
     public boolean onTouchEvent(MotionEvent event) { 

      switch (event.getAction() & MotionEvent.ACTION_MASK) { 

       case MotionEvent.ACTION_DOWN: 
        mode = DRAG; 

        //We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated 
        //amount for each coordinates This works even when we are translating the first time because the initial 
        //values for these two variables is zero.    
        startX = event.getX() - previousTranslateX; 
        startY = event.getY() - previousTranslateY; 
        break; 

       case MotionEvent.ACTION_MOVE:    
        translateX = event.getX() - startX; 
        translateY = event.getY() - startY; 

        //We cannot use startX and startY directly because we have adjusted their values using the previous translation values. 
        //This is why we need to add those values to startX and startY so that we can get the actual coordinates of the finger. 
        double distance = Math.sqrt(Math.pow(event.getX() - (startX + previousTranslateX), 2) + 
               Math.pow(event.getY() - (startY + previousTranslateY), 2) 
               ); 

        if(distance > 0) { 
         dragged = true; 
        }    

        break; 

       case MotionEvent.ACTION_POINTER_DOWN: 
        mode = ZOOM; 
        break; 

       case MotionEvent.ACTION_UP: 
        mode = NONE; 
        dragged = false; 

        //All fingers went up, so let's save the value of translateX and translateY into previousTranslateX and 
        //previousTranslate   
        previousTranslateX = translateX; 
        previousTranslateY = translateY; 
        break; 

       case MotionEvent.ACTION_POINTER_UP: 
        mode = DRAG; 

        //This is not strictly necessary; we save the value of translateX and translateY into previousTranslateX 
        //and previousTranslateY when the second finger goes up 
        previousTranslateX = translateX; 
        previousTranslateY = translateY; 
        break;  
      } 

      detector.onTouchEvent(event); 

      //We redraw the canvas only in the following cases: 
      // 
      // o The mode is ZOOM 
      //  OR 
      // o The mode is DRAG and the scale factor is not equal to 1 (meaning we have zoomed) and dragged is 
      // set to true (meaning the finger has actually moved) 
      if ((mode == DRAG && scaleFactor != 1f && dragged) || mode == ZOOM) { 
       invalidate(); 
      } 

      return true; 
     } 

     @Override 
     public void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 

      canvas.save(); 

      //We're going to scale the X and Y coordinates by the same amount 
      canvas.scale(scaleFactor, scaleFactor); 

      //If translateX times -1 is lesser than zero, let's set it to zero. This takes care of the left bound 
      if((translateX * -1) < 0) { 
       translateX = 0; 
      } 

      //This is where we take care of the right bound. We compare translateX times -1 to (scaleFactor - 1) * displayWidth. 
      //If translateX is greater than that value, then we know that we've gone over the bound. So we set the value of 
      //translateX to (1 - scaleFactor) times the display width. Notice that the terms are interchanged; it's the same 
      //as doing -1 * (scaleFactor - 1) * displayWidth 
      else if((translateX * -1) > (scaleFactor - 1) * displayWidth) { 
       translateX = (1 - scaleFactor) * displayWidth; 
      } 

      if(translateY * -1 < 0) { 
       translateY = 0; 
      } 

      //We do the exact same thing for the bottom bound, except in this case we use the height of the display 
      else if((translateY * -1) > (scaleFactor - 1) * displayHeight) { 
       translateY = (1 - scaleFactor) * displayHeight; 
      } 

      //We need to divide by the scale factor here, otherwise we end up with excessive panning based on our zoom level 
      //because the translation amount also gets scaled according to how much we've zoomed into the canvas. 
      canvas.translate(translateX/scaleFactor, translateY/scaleFactor); 

      /* The rest of your canvas-drawing code */ 
      canvas.restore(); 
     } 

     private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
      @Override 
      public boolean onScale(ScaleGestureDetector detector) { 
       scaleFactor *= detector.getScaleFactor(); 
       scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM)); 
       return true; 
      } 
     } 
    }