Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect touch speed in Android

Tags:

java

android

I added a drawable to my app that I can move with touch and based on the finger move speed, I'd like to do different actions.

I checked the events and I can only use MotionEvent.ACTION_MOVE to detect if there is movement. So I save the timestamp of the last movement and get the actual and I calculate the delta distance of the moving and use the formula of

speed=distance/time

However, the speed value show various numbers, from 0 to aprox. 6 but it doesn't matter if I use my finger slowly or fast. What should I modify to get the speed of the touch move?

I use the following code:

 @Override
  public boolean onTouch(View view, MotionEvent motionEvent)
  {

    final int X = (int) motionEvent.getRawX();
    final int Y = (int) motionEvent.getRawY();
    switch (motionEvent.getAction() & MotionEvent.ACTION_MASK)
    {
      case MotionEvent.ACTION_DOWN:
        RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
        _xDelta = X - lParams.leftMargin;
        _yDelta = Y - lParams.topMargin;
        oldTimeStamp=System.currentTimeMillis();
        break;
      case MotionEvent.ACTION_UP:
           speed=0;
           textView.setText("speed: " + speed);
        break;
      case MotionEvent.ACTION_POINTER_DOWN:
        break;
      case MotionEvent.ACTION_POINTER_UP:
        break;
      case MotionEvent.ACTION_MOVE:
        timeStamp= System.currentTimeMillis();
        long diff=timeStamp-oldTimeStamp;
        double dist=Math.sqrt(Math.pow(_xDelta,2)+Math.pow(_yDelta,2));
        double speed=dist/diff;
        textView.setText("speed: " + speed);
       oldTimeStamp=timeStamp;
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
        layoutParams.leftMargin = X - _xDelta;
        layoutParams.topMargin = Y - _yDelta;
        layoutParams.rightMargin = -250;
        layoutParams.bottomMargin = -250;
        view.setLayoutParams(layoutParams);
        break;

    }
    layoutRoot.invalidate();
    return true;
  }
like image 695
Nestor Avatar asked Jan 03 '14 21:01

Nestor


People also ask

How does Android detect touch?

Android supports detecting certain common gestures including single tap, double tap, long press, scroll and fling with GestureDetector . Implement an OnGestureListener , attach it to a GestureDetector and use it inside the View's OnTouchListener by passing it each touch event the View receives.

What is dispatchTouchEvent?

dispatchTouchEvent(MotionEvent) - This allows your Activity to intercept all touch events before they are dispatched to the window. • ViewGroup. onInterceptTouchEvent(MotionEvent) - This allows a ViewGroup to watch events as they are dispatched to child Views.

How do I turn off Touch listener on Android?

Use btn. setEnabled(false) to temporarily disable it and then btn. setEnabled(true) to enable it again.


1 Answers

@Override
public boolean onTouchEvent(MotionEvent event) {
    int index = event.getActionIndex();
    int action = event.getActionMasked();
    int pointerId = event.getPointerId(index);

    switch(action) {
        case MotionEvent.ACTION_DOWN:
            if(mVelocityTracker == null) {
                // Retrieve a new VelocityTracker object to watch the velocity of a motion.
                mVelocityTracker = VelocityTracker.obtain();
            }
            else {
                // Reset the velocity tracker back to its initial state.
                mVelocityTracker.clear();
            }
            // Add a user's movement to the tracker.
            mVelocityTracker.addMovement(event);
            break;
        case MotionEvent.ACTION_MOVE:
            mVelocityTracker.addMovement(event);
            // When you want to determine the velocity, call 
            // computeCurrentVelocity(). Then call getXVelocity() 
            // and getYVelocity() to retrieve the velocity for each pointer ID. 
            mVelocityTracker.computeCurrentVelocity(1000);
            // Log velocity of pixels per second
            // Best practice to use VelocityTrackerCompat where possible.
            Log.d("", "X velocity: " + 
                    VelocityTrackerCompat.getXVelocity(mVelocityTracker, 
                    pointerId));
            Log.d("", "Y velocity: " + 
                    VelocityTrackerCompat.getYVelocity(mVelocityTracker,
                    pointerId));
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            // Return a VelocityTracker object back to be re-used by others.
            mVelocityTracker.recycle();
            break;
    }
    return true;
}

Tracking Movement

Call mVelocityTracker.recycle() on view onDetachedFromWindow

like image 165
Triode Avatar answered Sep 19 '22 02:09

Triode