2015-12-23 7 views
6

ドラッグ可能なボタンを実装しようとしています。ドラッグアンドドロップ検出器が機能しない

残念ながら、ドラッグが開始された後、システムはMotionEventsの送信を停止します。したがって、GestureDetector.OnGestureListener.onFling()メソッドは決して呼び出されません。

ドラッグシステムによって消費される前に、これらのイベントをインターセプトする方法はありますか?

私も自分自身のFlingDetectorを作成しようとしましたが、それは別のデバイスと画面密度渡って信頼性がありません。

public class FlingDetector { 

private final int MIN_FLING_SPEED = 3; 

private OnFlingListener mOnFlingListener; 

private float mCurrentX = 0; 
private float mCurrentY = 0; 
private long mLastMovementTime = 0; 
private double mCurrentVelocity = 0; 

private final float mDensity; 

public FlingDetector(OnFlingListener onFlingListener, Context context) { 
    mOnFlingListener = onFlingListener; 
    mDensity = context.getResources().getDisplayMetrics().density; 
} 


public void onMovementStart(float x, float y) { 
    mCurrentX = x; 
    mCurrentY = y; 
    mLastMovementTime = System.currentTimeMillis(); 
    mCurrentVelocity = 0; 
} 

public void onMovementEnd(float x, float y) { 

    long currentTime = System.currentTimeMillis(); 

    float distanceX = Math.abs(mCurrentX - x)/mDensity; 
    float distanceY = Math.abs(mCurrentY - y)/mDensity; 

    float distance = (float) Math.sqrt(Math.pow(distanceX, 2) + 
      Math.pow(distanceY, 2)); 

    mCurrentVelocity = (distance/(currentTime - mLastMovementTime)); 

    if(mCurrentVelocity > MIN_FLING_SPEED) { 
     mOnFlingListener.onFling((int) (mCurrentVelocity + 0.5)); 
    } else { 
     Log.d("test", "Distance: " + distance); 
     Log.d("test", "Time Delta: " + (currentTime - mLastMovementTime)); 
     Log.d("test", "Speed: " + mCurrentVelocity); 
    } 
} 

public interface OnFlingListener { 
    void onFling(int speed); 
} 

} 
+0

私はライブラリで同様のものを実装しました。 'GestureDetectorCompat' [here](https://github.com/ericbhatti/floaties/blob/master/FloatiesLibrary/floaties/src/main/java/com/bezyapps/floatieslibrary/Floaty.java)を参照してください。それが役に立てば幸い。 –

+0

@timoschloesserドラッグしている間に場所にアクセスしようとしています....場所が非常に速く変化した場合。それは飛んでいる。 getAction()とACTION_DRAG_LOCATIONを試してみてください。私はあなたがどのようにスピードを測定できるのか分かりません。 –

答えて

0

あなたはGestureDetectorを使用して、ボタンと情事とドラッグの両方を達成することができます。 GestureDetectorは少しストレートですが、次のモーションイベントを処理する独自のDefaultメソッドを持っています。

  1. LongPress
  2. 情事
  3. onDown
  4. onShowPress
  5. onSingleTapUp
  6. onScroll

あなたはこのように実装することができます。

public class MainActivity extends AppCompatActivity { 

    Button button; 
    GestureDetector buttonGestureDetector; 
    static final int SWIPE_MIN_DISTANCE = 60; 
    static final int SWIPE_THRESHOLD_VELOCITY = 100; 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     button=(Button) findViewById(R.id.button); 

     buttonGestureDetector=new GestureDetector(this,new GestureDetector.OnGestureListener() { 
      @Override 
      public boolean onDown(MotionEvent e) { 
       return false; 
      } 

      @Override 
      public void onShowPress(MotionEvent e) { 

      } 

      @Override 
      public boolean onSingleTapUp(MotionEvent e) { 
       return false; 
      } 

      @Override 
      public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
       return false; 
      } 

      @Override 
      public void onLongPress(MotionEvent e) { 
       Log.i("Drag","DragListening"); 
       View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(button); 
       button.startDrag(null, shadowBuilder, button, 0); 
       button.setVisibility(View.INVISIBLE); 



      } 

      @Override 
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 

       Log.i("FlingListened","FlingListened"); 

       if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
        Toast.makeText(MainActivity.this,"OnRightToLeft Fling",Toast.LENGTH_SHORT).show(); 
       } 
       else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) 
       { 
        Toast.makeText(MainActivity.this,"OnLeftToRight Fling",Toast.LENGTH_SHORT).show(); 
       } 
       if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { 

        Toast.makeText(MainActivity.this,"onBottomToTop Fling",Toast.LENGTH_SHORT).show(); 

       } 
       else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { 
        Toast.makeText(MainActivity.this,"OnTopToBottom Fling",Toast.LENGTH_SHORT).show(); 

       } 
       return true; 


      } 
     }); 

     button.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       buttonGestureDetector.onTouchEvent(event); 
       return false; 


      } 
     }); 

      button.setOnDragListener(new View.OnDragListener() { 
      @Override 
      public boolean onDrag(View dragView, DragEvent event) 
      { 

       int action = event.getAction(); 
       switch (action) { 
        case DragEvent.ACTION_DRAG_STARTED: 
         Log.d("Drag", "Drag event started"); 
         break; 
        case DragEvent.ACTION_DRAG_ENTERED: 
         Log.d("Drag", "Drag event entered into "+dragView.toString()); 
         break; 
        case DragEvent.ACTION_DRAG_EXITED: 
         Log.d("Drag", "Drag event exited from "+dragView.toString()); 
         break; 
        case DragEvent.ACTION_DROP: 
         Log.d("Drag", "Dropped"); 
         View view = (View) event.getLocalState(); 
         ViewGroup owner = (ViewGroup) view.getParent(); 
         owner.removeView(view); 
         LinearLayout container = (LinearLayout) dragView; 
         container.addView(view); 
         view.setVisibility(View.VISIBLE); 
         break; 
        case DragEvent.ACTION_DRAG_ENDED: 
         Log.d("Drag", "Drag ended"); 
         break; 
        default: 
         break; 
       } 
       return true; 
      } 


     }); 

    } 
} 
関連する問題