How to detect a swipe event without lifting your finger

I want to increase / decrease the number while continuously scrolling / scrolling down. I could implement simple scroll events using the GestureDetector and OnSwipeTouchListener.

However, this swipe event is recognized only when the finger rises after the swipe. Therefore, to increase the number to +5, I have to do 5 separate scrolls on the screen.

I want to use the β€œslider” as an action so that the number changes when the user clicks up or down anywhere on the screen. (I do not want to use the Slider widget).

Is it possible?

Any help would be truly appreciated. Thanks!

+4
source share
3 answers

Use 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; } } } 
+6
source

@ 1up, thanks for the solution!

An improvement that I could add, even if the scroll direction is reversed without raising my finger, it will work well.

Using the skeleton you gave by posting my code, hoping this helps someone in the future ...

 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 XY 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 XY 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 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 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 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 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() { } } 
+5
source

So, I wrote my own version of the direction listener.


NOTE: THIS EXTENDS YOU ABOUT THE DIRECTION OF SWITCHING ON A CONTINUOUS SEX!

 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 ie 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 ie 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 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) { } } 

And it works like a charm!

Implementation:

 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); } }); 
0
source

Source: https://habr.com/ru/post/1502259/


All Articles