Получите скорость события перемещения действия onTouch в Android

Это должно быть довольно просто сделать. Пользователь кладет палец на экран и водит им по экрану. На onTouch есть два события:

  • MotionEvent.ACTION_DOWN
  • MotionEvent.ACTION_MOVE

теперь, как я могу рассчитать скорость жеста ACTION_MOVE ? Пользователь перетаскивает палец медленнее или быстрее во время жеста, поэтому я думаю, что мне нужно рассчитать скорость между двумя промежуточными точками касания: lastTouchedPointX, lastTouchedPointY и событие.getX(),событие.Гети ().

кто-нибудь делал это раньше ?

4 ответов


@Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView) {


            if(event.getAction() == MotionEvent.ACTION_DOWN) {

                oldX = event.getX();
                oldY = event.getY();
                    //start timer

            } else if (event.getAction() == MotionEvent.ACTION_UP) {   

                //long timerTime = getTime between two event down to Up
                newX = event.getX();
                newY = event.getY();

                float distance = Math.sqrt((newX-oldX) * (newX-oldX) + (newY-oldY) * (newY-oldY));
                float speed = distance / timerTime;

            }
}

чего вам нужно можно достигнуть путем использование стандарта VelocityTracker класса. Подробнее о Google Лучшая практика для пользовательского ввода при отслеживании движения здесь. Большая часть кода ниже (который демонстрирует использование VelocityTracker отображая скорость по оси X и Y каждого броска / движения) берется из предыдущей ссылки ресурса:

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.VelocityTrackerCompat;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.TextView;

public class MainActivity extends Activity {

    private VelocityTracker mVelocityTracker = null;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTextView = new TextView(this);
        mTextView.setText("Move finger on screen to get velocity.");
        setContentView(mTextView);
    }

    @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.
            mTextView.setText("X velocity: "
                    + VelocityTrackerCompat.getXVelocity(mVelocityTracker,
                            pointerId)
                    + "\nY velocity: "
                    + VelocityTrackerCompat.getYVelocity(mVelocityTracker,
                            pointerId));
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_CANCEL:
            // Return a VelocityTracker object back to be re-used by others.
            mVelocityTracker.recycle();
            break;
        }
        return true;
    }

}

Это вопрос о том, как точно вы хотите выполнить этот расчет.

однако основная процедура состоит в том, чтобы получить временную метку каждой соответствующей пары ACTION_DOWN, ACTION_UP и вычислить разницу.

затем вам нужно определить покрытые пиксели. Это можно сделать с помощью простой тригонометрии.

когда у вас есть разница во времени и покрытые пиксели, вы можете рассчитать пиксели за скорость времени в среднем из двух точек (вниз и вверх).

вы можете сделать это для каждой точки, когда палец движется по экрану, чтобы получить лучший результат.


изображение на холсте с сенсорными событиями из этого примера получите время события касания и вычислите время и расстояние, чтобы получить скорость