7

で奇妙な問題が発生していOnDragListenerます。私のターゲットビューはACTION_DROPイベントを正常に取得して処理します。ただし、ACTION_DRAG_STARTEDorACTION_DRAG_ENDEDイベントを受け取ることはありません (実際、ドロップ以外のイベントを受け取ることはありません)。

何が原因でしょうか? ドロップがターゲットの外で発生した場合を処理できないため、問題です。

この質問を見つけましたが、答えは明確ではありませんでした。どんなアイデアでも大歓迎です。

私のドラッグ可能なビューにはこれがありますOnTouchListener

@Override
public boolean onTouch(View v, MotionEvent ev) {
  switch (ev.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
      startPointX = ev.getX();
      startPointY = ev.getY();
      isOnClick = true;
      break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
      if (isOnClick) {
        isOnClick = false;
        // handle single click
      }
      break;
    case MotionEvent.ACTION_MOVE:
      if (isOnClick && movePassesThreshold(ev)) {
        isOnClick = false;
        draggableView.startDrag(...);
      }
      break;
    default:
      break;
  }
  return true;
}

そして、ターゲットビューにはこれがありますOnDragListener:

@Override
public boolean onDrag(View v, DragEvent event) {
  switch (event.getAction()) {
    case DragEvent.ACTION_DRAG_STARTED:
      Log.v(TAG, "drag started");
      break;
    case DragEvent.ACTION_DRAG_ENTERED:
      break;
    case DragEvent.ACTION_DRAG_EXITED:
      break;
    case DragEvent.ACTION_DROP:
      Log.v(TAG, "drop");
      // handle drop
      break;
    case DragEvent.ACTION_DRAG_ENDED:
      Log.v(TAG, "drag ended");
      break;
    default:
      return false;
  }
  return true;
}
4

3 に答える 3

2

私の解決策は次の回避策ですOnTouchListener。ACTION_UP を取得したら、1 秒の遅延ランナブルを設定して、ビューがまだドラッグされているかどうかを確認します。OnDragListenerがドロップを受け取った場合、ランナブルは何もしません。ただし、実行可能な呼び出しがドラッグを停止しない場合は、ビューをクリーンアップして以前の位置にリセットします。

case MotionEvent.ACTION_UP:
  if (isOnClick) {
    isOnClick = false;
    // handle single click
  } else if (draggableView.isDragging()) {
    uiHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        if (draggableView.isDragging()) {
          // Drop never got received, so call stopDrag
          draggableView.stopDrag();
        }
      }
    }, 1000);
  }
  break;
于 2013-10-18T21:30:24.717 に答える
0

これが私がやっている方法です。それがあなたにとってうまくいくかどうかはわかりませんが、それでも投稿します。

@Override
public boolean onTouch(View v, MotionEvent event) {
         final ClipData data = ClipData.newPlainText("position",position + "");
         v.startDrag(data, pieceDragShadowBuilder, v, 0);
         return true;
}

次に、リスナーでその:

                @Override
                public boolean onDrag(View pV, DragEvent pEvent) {
                  final int dragAction = pEvent.getAction();

                  View dragView = (View) pEvent.getLocalState();
                  final FrameLayout container = (FrameLayout) pV;

                            if (dragAction == DragEvent.ACTION_DRAG_STARTED)
                            {

                            } 
                            else if (dragAction == DragEvent.ACTION_DRAG_ENTERED)
                            {

                            }
                            else if (dragAction == DragEvent.ACTION_DRAG_EXITED) 
                            {

                            } 
                            else if (dragAction == DragEvent.ACTION_DROP) 
                            {

                            }

あなたのコードとの唯一の違いは、MOVE、UP、または CANCEL の特定のイベントに関係なく、startDrag()メソッドを呼び出していることです。onTouch()

于 2013-10-17T19:19:44.440 に答える