6

私はビューをドラッグするためのonTouchListenerを作成しました。 getRawX()getRawY()を使用すると、画像がスムーズにドラッグされます。その問題は、2番目のポインタを下にして最初のポインタを上げると、イメージが2番目のポインタにジャンプすることです。ドラッグ中にImageViewをジャンプします。 getX()とgetY()の値がジャンプしています

このonTouchListenerは、pointerIdを追跡することによってその問題を解決しようとします。このonTouchListenerの問題は、ImageViewをドラッグしている間にImageViewがかなり狂ってジャンプしてしまうことです。 getX()getY()の値がジャンプします。

私はこれを正しくやっているように感じます。私はすでにscaleGestureDetectorを実装していてカスタムのrotateGestureDetectorを記述しているため、カスタムビューを作成する必要はありません。すべて正常に動作しますが、私はgetRawX()getRawY()を使用するときに得られる問題を解決する必要があります。

私がここで間違っていることを誰かが知っていますか?ここで

は私のonTouchListenerです:

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

誰にも解決策がありますか?他の人がこの問題に遭遇したようですが、まだ解決策が見つかりませんでした。 –

答えて

10

問題は単純でしたが、予想外でした。 getRawX/Y()は絶対座標を返し、getX/Y()はビューに対して相対座標を返します。私はビューを移動し、lastX/Yをリセットし、イメージはもう同じ場所にはないので、新しい値を取得するとオフになります。この場合、私は元々が画像を押したところでのみ必要でした( `getRawX/Y 'を使用している場合ではありません)。

ので、解決策は単純に次を削除することでした:

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

(私はこの問題に他人を見てきたので、これは、将来的に誰かを助けることを願っています、そして、彼らは私に似たコードを持っていましたリセットlastX/Y

+0

うれしい私はこれを見つけました!私は多くの人がhttp://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.htmlを読んでlastX/LastYを保存するコードを持っていると思う。どうやら、ビューを動かす状況は、キャンバスが翻訳されている「マルチタッチ」の例とは異なります。最後のコメントはhttp://stackoverflow.com/questions/16676097/android-getx-gety-interleaves-relative-absolute-coordinates?rq=1で、彼がview.setX()の設定をコメントアウトし、 view.setY()、onTouch()中の絶対座標と相対座標のインタリーブが停止しました。 –

+0

@ T.Folsom Glad私は助けることができました!はい、多くの人が最初のリンクの後に自分のコードをモデル化しています。私が知る限り、 'getX()'と 'getY()'は常に相対座標を返します。彼の座標は私と同じ理由で飛び降りていた。彼はビューが移動した後、ビューが移動したために異なる相対座標を取得します。それは理にかなっていますか? –

+0

はい、これはより多くの人々を助けました:) – Nate

0

私はワンチップ&を持って、それが助けになると思います。あなたが使用する必要がありますどのような

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

requestLayout()です:測定とレイアウトプロセスを行います。 & requestLayout()setLayoutParams()と呼ぶと思います。

のでv.invalidate()

を除去することによって、試してみてくださいまたはview.layout(left,top,right,bottom)メソッドを使用して代わりにlayoutParamsを設定してみてください。

+0

私はこのシナリオでは役に立たないと思ったので、以前は 'v.invalidate()'を削除しようとしました(提案してからもう一度試しました)。私はそれを 'v.requestLayout()'に置き換えようとしましたが、それは動作を変更しませんでした:/その他の提案? –

+0

'forceLayout()'のダイスが –

+0

でないか、またはlayoutParamsを設定する代わりにview.layout(left、top、right、bottom)メソッドを使用してみてください。 – vakman

0

多くの研究の後、私はこれが問題であることを発見しました.getRawXは絶対的でgetXはビューに対して相対的です。したがって、これを使用して1つを別のものに変換してください。

//RawX = getX + View.getX 

event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX() 
関連する問題