【问题标题】:How to detect swipe event without finger lift如何在没有手指抬起的情况下检测滑动事件
【发布时间】:2015-09-22 03:20:42
【问题描述】:

我想在连续向上滑动/向下滑动事件中增加/减少一个数字。 我可以使用 GestureDetector 和 OnSwipeTouchListener 实现简单的滑动事件。

但是,只有在滑动后抬起手指时才会感应到此滑动事件。 因此,要将数字增加到 +5,我必须在屏幕上进行 5 次单独向上滑动。

我想应用类似“滑块”的操作,以便在用户在屏幕上的任意位置向上或向下滑动时更改数字。 (我不想使用“滑块”小部件)。

这可能吗?

任何帮助将不胜感激。 谢谢!

【问题讨论】:

    标签: android


    【解决方案1】:

    使用 OnTouchListener:

    private float baseX, baseY;
    
    OnTouchListener listener = new OnTouchListener(){
        public boolean onTouch (View v, MotionEvent event)
        {
            switch(event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    //TOUCH STARTED
                    baseX = event.getX();
                    baseY = event.getY();
                    return true;
                case MotionEvent.ACTION_MOVE:
                    //FINGER IS MOVING
                    //Do your calculations here, using the x and y positions relative to the starting values you get in ACTION_DOWN
                    return true;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    //TOUCH COMPLETED
                    return true;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      @1up,非常感谢您的解决方案!

      我可以添加的一项增强功能是,即使在不抬起手指的情况下反转滑动方向,它也能正常工作。

      使用您提供的骨架,发布我的代码,希望将来能对某人有所帮助...

      public class OnSwipeListener implements OnTouchListener
      {
          @Override
          public boolean onTouch(View v, MotionEvent event) 
          {
          boolean result = false;
      
          float currentX      = 0.0f;
          float currentY      = 0.0f;
      
          float current_diffX = 0.0f;
          float current_diffY = 0.0f;
      
          switch(event.getAction())
          {
              case MotionEvent.ACTION_DOWN:
                  //Touch detected, record base X-Y coordinates
                  baseX = event.getX();
                  baseY = event.getY();
      
                  //As the event is consumed, return true
                  result = true;  
                  break;
      
              case MotionEvent.ACTION_MOVE:
                  //Swipe started, get current X-Y coordinates and compute those with the base ones
                  currentX = event.getX();
                  currentY = event.getY();
      
                  current_diffX = currentX - baseX;
                  current_diffY = currentY - baseY;
      
                  //...................................................Determine horizontal swipe direction
                  if(h_swipe == LEFT_SWIPE)
                  {
                      if( currentX > previousX )
                      {
                          //If here, then horizontal swipe has been reversed
                          h_swipe = RIGHT_SWIPE;
      
                          //Overwrite base coordinate
                          baseX = previousX;
      
                          //Recalculate Difference
                          current_diffX = currentX - baseX;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }
                  }
                  else if(h_swipe == RIGHT_SWIPE)
                  {
                      if( currentX < previousX )
                      {
                          //If here, then horizontal swipe has been reversed
                          h_swipe = LEFT_SWIPE;
      
                          //Overwrite base coordinate
                          baseX = previousX;
      
                          //Recalculate Difference
                          current_diffX = currentX - baseX;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }                   
                  }
                  else
                  {
                      //If here, then it's a fresh swipe event, so compare with base coordinates
                      if( currentX < baseX )
                      {
                          h_swipe = LEFT_SWIPE;
                      }
                      else if( currentX > baseX )
                      {
                          h_swipe = RIGHT_SWIPE;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }
                  }
      
                  //...................................................Determine vertical swipe direction 
                  if(v_swipe == UP_SWIPE)
                  {
                      if(currentY > previousY)
                      {
                          //If here, then vertical swipe has been reversed
                          v_swipe = DOWN_SWIPE;
      
                          //Overwrite base coordinate
                          baseY = previousY;
      
                          //Recalculate coordinate difference
                          current_diffY = currentY - baseY;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }
                  }
                  else if(v_swipe == DOWN_SWIPE)
                  {
                      if(currentY < previousY)
                      {
                          //If here, then vertical swipe has been reversed
                          v_swipe = UP_SWIPE;
      
                          //Overwrite base coordinate
                          baseY = previousY;
      
                          //Recalculate coordinate difference
                          current_diffY = currentY - baseY;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }
                  }
                  else
                  {
                      //If here, then it's a fresh swipe event, so compare with base coordinates
                      if( currentY < baseY )
                      {
                          v_swipe = UP_SWIPE;
                      }
                      else if( currentY > baseY )
                      {
                          v_swipe = DOWN_SWIPE;
                      }
                      else
                      {
                          //NOP - Intentionally kept empty
                      }
                  }
      
                  //Record current coordinates for future comparisons
                  previousX = currentX;
                  previousY = currentY;
      
                  //................................Determine the prominent swipe (horizontal/vertical)
                  if(Math.abs(current_diffX) > Math.abs(current_diffY))
                  {
                      //It's a horizontal swipe
                      if (Math.abs(current_diffX) > SWIPE_THRESHOLD) 
                      {
                          if (current_diffX > 0) 
                          {
                              onRightSwipe();
                          } 
                          else 
                          {
                              onLeftSwipe();
                          }
                      }
                      else
                      {
                          //Not enough swipe movement, ignore.
                          //NOP - Intentionally kept empty
                      }
                  }
                  else
                  {
                      //It's a vertical swipe
                      if (Math.abs(current_diffY) > SWIPE_THRESHOLD) 
                      {
                          if (current_diffY > 0) 
                          {
                              onDownSwipe();
                          } 
                          else 
                          {
                              onUpSwipe();
                          }
                      }
                      else
                      {
                          //Not enough swipe movement, ignore.
                          //NOP - Intentionally kept empty
                      }                   
                  }
      
                  //As the event is consumed, return true
                  result = true;
                  break;
      
              case MotionEvent.ACTION_UP:
                  //Swipe ended, clear variables, if necessary
                  h_swipe = NO_H_SWIPE;
                  v_swipe = NO_V_SWIPE;
      
                  baseX = 0.0f;
                  baseY = 0.0f;
      
                  previousX = 0.0f;
                  previousY = 0.0f;
      
                  //As the event is consumed, return true
                  result = true;              
                  break;
      
              default:
      
                  //Do not consume event
                  result = false;
                  break;
          }
      
          return result;
      }
      
      
      public void onUpSwipe()
      {
      
      }
      
      public void onDownSwipe()
      {
      
      }
      
      public void onRightSwipe()
      {
      
      }
      
      public void onLeftSwipe()
      {
      
      }
      }
      

      【讨论】:

      • 很多符号在这个实现中没有被解析。不知道他们中的大多数人是什么!
      【解决方案3】:

      所以我写了我自己版本的方向监听器。


      注意:它会告诉您在连续触摸会话上的滑动方向!

      import android.view.MotionEvent;
      import android.view.View;
      
      public class SwipeDirectionListener implements View.OnTouchListener {
      
      float deltaX ;
      float deltaY ;
      float maxValX;
      float maxValY;
      float firstTouchX;
      float firstTouchY;
      float currentX ;
      float currentY ;
      float SWIPE_THRESHOLD = 10.0f;
      
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          boolean result ;
      
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  //Register the first touch on TouchDown and this should not change unless finger goes up.
                  firstTouchX = event.getX();
                  firstTouchY = event.getY();
                  maxValX = 0.0f;
                  maxValY = 0.0f;
                  //As the event is consumed, return true
                  result = true;
                  break;
      
              case MotionEvent.ACTION_MOVE:
                  //CurrentX/Y are the continues changing values of one single touch session. Change
                  //when finger slides on view
                  currentX = event.getX();
                  currentY = event.getY();
                 //setting the maximum value of X or Y so far. Any deviation in this means a  change of direction so reset the firstTouch value to last known max value i.e MaxVal X/Y.
                  if(maxValX <currentX){
                      maxValX = currentX;
                  }else{
                      firstTouchX= maxValX;
                      maxValX =0.0f;
                  }
      
                  if(maxValY <currentY){
                      maxValY = currentY;
                  }else{
                      firstTouchY= maxValY;
                      maxValY =0.0f;
                  }
                  //DeltaX/Y are the difference between current touch and the value when finger first touched screen.
                  //If its negative that means current value is on left side of first touchdown value i.e Going left and
                  //vice versa.
                  deltaX = currentX - firstTouchX;
                  deltaY = currentY - firstTouchY;
      
                  if (Math.abs(deltaX) > Math.abs(deltaY)) {
                      //Horizontal swipe
                      if (Math.abs(deltaX) > SWIPE_THRESHOLD) {
                          if (deltaX > 0) {
                              //means we are going right
                              onRightSwipe(currentX);
                          } else {
                              //means we are going left
                              onLeftSwipe(currentX);
                          }
                      } 
                  } else {
                      //It's a vertical swipe
                      if (Math.abs(deltaY) > SWIPE_THRESHOLD) {
                          if (deltaY > 0) {
                              //means we are going down
                              onDownSwipe(currentY);
                          } else {
                              //means we are going up
                              onUpSwipe(currentY);
                          }
                      } 
                  }
      
                  result = true;
                  break;
      
              case MotionEvent.ACTION_UP:
                  //Clean UP
                  firstTouchX = 0.0f;
                  firstTouchY = 0.0f;
      
                  result = true;
                  break;
      
              default:
                  result = false;
                  break;
          }
      
          return result;
      }
      
      
      public void onUpSwipe(float value) {
      
      }
      
      public void onDownSwipe(float value) {
      
      }
      
      public void onRightSwipe(float value) {
      
      }
      
      public void onLeftSwipe(float value) {
      
      }
      }
      

      这就像一个魅力!

      实施:

      yourView.setOnTouchListener(new SwipeDirectionListener() {
              public void onUpSwipe(float value) {
      
                  mTextView.setText("onUpSwipe :"+value);
              }
      
              public void onDownSwipe(float value) {
                  mTextView.setText("onDownSwipe :"+value);
              }
      
              public void onRightSwipe(float value) {
                  mTextView.setText("onRightSwipe :"+value);
              }
      
              public void onLeftSwipe(float value) {
                  mTextView.setText("onLeftSwipe :"+value);
              }
          });
      

      【讨论】:

      • 我不明白为什么是负数,为什么不像向下滑动那样增加
      • @dacastro4 你可以在官方文档中阅读。 X 和 Y 值在屏幕上始终是相对的。它们可能是负面的。
      • MotionEvent的官方文档?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      相关资源
      最近更新 更多