获取 Android 中 onTouch ACTION_MOVE 事件的速度

发布于 2024-11-03 12:23:46 字数 297 浏览 1 评论 0原文

这应该是一件非常简单的事情。用户将手指放在屏幕上并在屏幕上拖动。 onTouch 上触发了两个事件:

  • MotionEvent.ACTION_DOWN
  • MotionEvent.ACTION_MOVE

现在,如何计算 ACTION_MOVE 手势的速度?用户在手势过程中将手指拖动得更慢或更快,所以我想我需要计算两个中间触摸点之间的速度:lastTouchedPointX、lastTouchedPointY 和 event.getX()、event.getY()。

以前有人这样做过吗?

This should be a pretty simple thing to do. The user puts his finger on the screen and drags it around the screen. There are two events firing on onTouch:

  • MotionEvent.ACTION_DOWN
  • MotionEvent.ACTION_MOVE

Now, how can I calculate the speed of the ACTION_MOVE gesture ? The user drags the finger slower or faster during a gesture, so I think I need to calculate the speed between two intermediate touched points: the lastTouchedPointX,lastTouchedPointY and the event.getX(),event.getY().

Has anyone done this before ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酷炫老祖宗 2024-11-10 12:23:46

您可以通过使用标准 VelocityTracker< /a> 类。有关跟踪运动时 Google 用户输入最佳实践的更多详细信息此处< /a>.下面的大部分代码(通过显示每次滑动/移动的 X 轴和 Y 轴速度来演示 VelocityTracker 的使用)取自之前的资源链接:

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;
    }

}

What you need can be achieved by using the standard VelocityTracker class. More details on Google's Best Practice for User Input while tracking movement here. Most of the code below (which demonstrates the use of VelocityTracker by displaying the speed on X and Y axis of each fling/move) is taken from the previous resource link:

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;
    }

}
漆黑的白昼 2024-11-10 12:23:46
@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;

            }
}
@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;

            }
}
彻夜缠绵 2024-11-10 12:23:46

问题在于您希望执行此计算的准确性如何。

然而,基本过程是获取每个对应的 ACTION_DOWN、ACTION_UP 对的时间戳并计算差值。

然后你需要确定被覆盖的像素。这可以通过简单的三角学来完成。

当您同时具有时间差和覆盖像素时,您可以将单位时间速度的像素计算为两点(向下和向上)的平均值。

当手指在屏幕上移动时,您可以对每个点执行此操作,以获得更好的结果。

It's a question about how accurate you want to perform this calculation.

However the basic procedure is to get the timestamp of each corresponding ACTION_DOWN, ACTION_UP couple and calculate the difference.

Then you need to determine the covered pixels. This could be done with simple trigonometry.

When you have both time difference and covered pixels you can calculate the pixels per time speed as an average of the two points (down and up).

You can do this for every point when the finger is moving over the screen to get a better result.

惜醉颜 2024-11-10 12:23:46

带有触摸事件的画布中的图像
从这个例子中获取触摸事件时间和计算时间&获得速度的距离

Image in Canvas with touch events
from this example get touch event time & calculate time & distance to get speed

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文