6

Tôi đã tạo một onTouchListener để kéo Chế độ xem. Hình ảnh kéo mượt mà nếu tôi sử dụng getRawX()getRawY(). Vấn đề với đó là hình ảnh sẽ nhảy đến con trỏ thứ hai khi bạn đặt con trỏ thứ hai xuống rồi nhấc con trỏ đầu tiên lên.Nhảy ImageView trong khi kéo. Các giá trị getX() và getY() đang nhảy

OnTouchListener này cố gắng khắc phục sự cố đó bằng cách theo dõi pointerId. Vấn đề với onTouchListener này là trong khi kéo một ImageView, ImageView nhảy xung quanh khá điên cuồng. Giá trị getX()getY() nhảy xung quanh.

Tôi cảm thấy như tôi đang làm điều này một cách chính xác. Tôi không muốn phải viết một cái nhìn tùy chỉnh cho điều này bởi vì tôi đã thực hiện một scaleGestureDetector và viết một rotationGestureDetector tùy chỉnh hoạt động. Mọi thứ đều hoạt động tốt nhưng tôi cần khắc phục sự cố tôi nhận được khi sử dụng getRawX()getRawY().

Có ai biết tôi đang làm gì sai ở đây không?

Dưới đây là onTouchListener tôi:

final View.OnTouchListener onTouchListener = new View.OnTouchListener() 
{ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     relativeLayoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams(); 

     final int action = event.getAction(); 
     switch (action & MotionEvent.ACTION_MASK) 
     { 
      case MotionEvent.ACTION_DOWN: 
      { 
       final float x = event.getX(); 
       final float y = event.getY(); 

       // Where the user started the drag 
       lastX = x; 
       lastY = y; 
       activePointerId = event.getPointerId(0); 
       break; 
      } 
      case MotionEvent.ACTION_MOVE: 
      { 
       // Where the user's finger is during the drag 
       final int pointerIndex = event.findPointerIndex(activePointerId); 
       final float x = event.getX(pointerIndex); 
       final float y = event.getY(pointerIndex); 

       // Calculate change in x and change in y 
       final float dx = x - lastX; 
       final float dy = y - lastY; 

       // Update the margins to move the view 
       relativeLayoutParams.leftMargin += dx; 
       relativeLayoutParams.topMargin += dy; 
       v.setLayoutParams(relativeLayoutParams); 

       // Save where the user's finger was for the next ACTION_MOVE 
       lastX = x; 
       lastY = y; 

       v.invalidate(); 
       break; 
      } 
      case MotionEvent.ACTION_UP: 
      { 
       activePointerId = INVALID_POINTER_ID; 
       break; 
      } 
      case MotionEvent.ACTION_CANCEL: 
      { 
       activePointerId = INVALID_POINTER_ID; 
       break; 
      } 
      case MotionEvent.ACTION_POINTER_UP: 
      { 
       // Extract the index of the pointer that left the touch sensor 
       final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
       final int pointerId = event.getPointerId(pointerIndex); 

       if(pointerId == activePointerId) 
       { 
        // This was our active pointer going up. Choose a new 
        // active pointer and adjust accordingly 
        final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
        lastX = (int) event.getX(newPointerIndex); 
        lastY = (int) event.getY(newPointerIndex); 
        activePointerId = event.getPointerId(newPointerIndex); 
       } 
       break; 
      } 
     } 
     return true; 
    } 
}; 
image1.setOnTouchListener(onTouchListener); 
+0

Bất kỳ ai có giải pháp này? Có vẻ như những người khác đã gặp phải vấn đề này, nhưng tôi vẫn chưa tìm được giải pháp nào. –

Trả lời

10

Vấn đề rất đơn giản nhưng không mong muốn. getRawX/Y() trả lại tọa độ tuyệt đối, trong khi getX/Y() trả về tọa độ tương ứng với chế độ xem. Tôi sẽ di chuyển chế độ xem, đặt lại lastX/Y và hình ảnh sẽ không ở cùng vị trí nữa vì vậy khi tôi nhận được các giá trị mới, chúng sẽ bị tắt. Trong trường hợp này tôi chỉ cần ở nơi tôi ban đầu nhấn hình ảnh (không phải trường hợp khi sử dụng `getRawX/Y ').

Vì vậy, giải pháp là chỉ cần loại bỏ những điều sau đây:

// Save where the user's finger was for the next ACTION_MOVE 
lastX = x; 
lastY = y; 

Tôi hy vọng điều này sẽ giúp ai đó trong tương lai, bởi vì tôi đã nhìn thấy những người khác với vấn đề này, và họ đã có mã tương tự như đối với tôi (đặt lại lastX/Y)

+0

Rất vui khi tôi tìm thấy điều này! Tôi nghi ngờ nhiều người có mã để lưu lastX/LastY vì đọc http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html. Rõ ràng tình hình di chuyển một khung nhìn khác với ví dụ trong "cảm ứng đa điểm", nơi canvas đang được dịch. Nhận xét cuối cùng ở đây, http://stackoverflow.com/questions/16676097/android-getx-gety-interleaves-relative-absolute-coordinates?rq=1, lưu ý rằng khi anh ấy nhận xét cài đặt của view.setX() và view.setY(), việc xen kẽ các tọa độ tuyệt đối và tương đối trong khi onTouch() dừng lại. –

+0

@ T.Folsom Vui vì tôi có thể giúp! Có, rất nhiều người lập mô hình mã của họ sau liên kết đầu tiên của bạn, bao gồm cả tôi. Theo như tôi biết, 'getX()' và 'getY()' luôn trả về các tọa độ tương đối. Các tọa độ của anh ta nhảy với cùng lý do như tôi. Anh di chuyển khung nhìn sau đó nhận các tọa độ tương đối khác nhau vì khung nhìn đã dịch chuyển. Điều đó có ý nghĩa? –

+0

Có, điều này đã giúp nhiều người hơn :) – Nate

0

Tôi có Một mẹo & nghĩ rằng nó sẽ giúp đỡ.

invalidate() : does only redrawing a view,doesn't change view size/position. 

Những gì bạn nên sử dụng là requestLayout(): hiện đo và bố trí quy trình. & tôi nghĩ rằng requestLayout() sẽ được gọi khi gọi setLayoutParams();

Vì vậy, Hãy thử bằng cách loại bỏ v.invalidate()

hoặc thử sử dụng phương pháp view.layout(left,top,right,bottom) thay vì thiết layoutParams.

+0

Tôi đã thử xóa 'v.invalidate()' trong quá khứ (đã thử lại lần nữa vì bạn đã đề xuất nó) vì tôi thấy nó vô dụng trong trường hợp này, không giúp ích gì. Tôi đã thử thay thế nó bằng 'v.requestLayout()' và điều đó không thay đổi hành vi:/Bất kỳ gợi ý nào khác? –

+0

không có súc sắc với 'forceLayout()' hoặc –

+0

hoặc thử sử dụng phương thức view.layout (trái, trên, phải, dưới) thay vì đặt layoutParams. – vakman

0

Sau nhiều nghiên cứu, tôi thấy đây là vấn đề, getRawX là tuyệt đối và getX là tương đối so với chế độ xem. do đó, hãy sử dụng điều này để chuyển đổi hình thức này sang một số khác

//RawX = getX + View.getX 

event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX()