Получите скорость события onTouch ACTION_MOVE в Android
Это должно быть довольно простой задачей. Пользователь нажимает палец на экран и перетаскивает его по экрану. В onTouch есть два события:
- MotionEvent.ACTION_DOWN
- MotionEvent.ACTION_MOVE
Теперь, как я могу рассчитать скорость жестов ACTION_MOVE? Пользователь тянет палец медленнее или быстрее во время жестов, поэтому я думаю, что мне нужно вычислить скорость между двумя промежуточными касательными точками: lastTouchedPointX, lastTouchedPointY и event.getX(), event.getY().
Кто-нибудь сделал это раньше?
Ответы
Ответ 1
@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;
}
}
Ответ 2
То, что вам нужно, может быть достигнуто с помощью стандартного класса VelocityTracker
. Подробнее о Google Best Practice для пользовательского ввода, отслеживая движение здесь. Большая часть приведенного ниже кода (который демонстрирует использование 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 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;
}
}
Ответ 3
Это вопрос о том, насколько точно вы хотите выполнить этот расчет.
Однако основная процедура заключается в том, чтобы получить временную метку каждой соответствующей пары ACTION_DOWN, ACTION_UP и вычислить разницу.
Затем вам нужно определить покрытые пиксели. Это можно сделать с помощью простой тригонометрии.
Когда у вас есть разность во времени и покрытые пиксели, вы можете вычислить пиксели на скорость времени в среднем по двум точкам (вниз и вверх).
Вы можете сделать это для каждой точки, когда палец перемещается по экрану, чтобы получить лучший результат.
Ответ 4
Изображение в холсте с событиями касания
из этого примера получите время события касания и вычислите время и расстояние, чтобы получить скорость