【问题标题】:Get speed of a onTouch ACTION_MOVE event in Android在 Android 中获取 onTouch ACTION_MOVE 事件的速度
【发布时间】:2011-08-14 12:44:40
【问题描述】:

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

  • MotionEvent.ACTION_DOWN
  • MotionEvent.ACTION_MOVE

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

以前有人做过吗?

【问题讨论】:

    标签: android performance gesture


    【解决方案1】:

    您需要的可以通过使用标准的VelocityTracker 类来实现。更多关于谷歌用户输入最佳实践的详细信息,同时跟踪移动here。下面的大部分代码(通过在 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;
        }
    
    }
    

    【讨论】:

      【解决方案2】:
      @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;
      
                  }
      }
      

      【讨论】:

      • @wadali 动作向下和动作向上之间的时间戳,查看评论
      • 距离 = Math.hypot(newX-oldX,newY-newY) en.wikipedia.org/wiki/Pythagorean_theorem
      • @bongjaechoe 两者都是相同的双距离 = Math.sqrt((newX - olddeltaX) * (newX - olddeltaX) + (newY - olddeltaY) * (newY - olddeltaY));双距离H = Math.hypot(newX - olddeltaX, newY - olddeltaY);
      【解决方案3】:

      这是一个关于您希望执行此计算的准确度的问题。

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

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

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

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

      【讨论】:

        【解决方案4】:

        Image in Canvas with touch events 从此示例获取触摸事件时间并计算时间和距离以获取速度

        【讨论】:

          猜你喜欢
          • 2013-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多