I've been playing around with motion event and drags (so I'm not lifting my finger off the screen - it's not a fling). The problem is that it only detects the second, third, forth and so on, drags moving down or up when my finger moves past the point of where the up drag or down drag starts and ends.
See code below. Count equals 2 when I drag up and 1 when I drag down. However, it only counts when, for example, I move my finger up (count 2) and then back down past the point of when I started moving up ( which will be count 1), not before that which would equal 2, and this continues as I move back up it counts 2 only when I move past the point of when I changed direction to go back down. But why doesn't it recognise it as a drag before those points, because any movement in those directions should be a drag. How do I resolve this?
Here's my simple code to test it:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
oldX = (int) event.getRawX();
oldY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
posY = (int) event.getRawY();
posX = (int) event.getRawX();
diffPosY = posY - oldY;
diffPosX = posX - oldX;
if (diffPosY > 0){//down
count = 1;
}
else//up
{
count = 2;
}
break;
If I understand what you're trying to do correctly, I think you need to update oldX
and oldY
in your case MotionEvent.ACTION_MOVE:
, after you've use it to set diffPosY
and diffPosX
because you're currently only setting oldX
and oldY
when the touch starts. So, after you've set diffPosY
and diffPosX
, add:
oldX = posX;
oldY = posY;
UPDATE
Because the motion events are processed frequently, you probably want to introduce some touch slop to account for the fact that when you place your finger on the screen you might move it very slightly down before you move up without realising it, and if you swipe slowly you might inadvertently swipe very slightly in the opposite direction to the way you think you're going. That looks like what's happening in what you saw in your comment below. The following code should help fix that, but will make it slightly slower to react to changes of direction:
// Get the distance in pixels that a touch can move before we
// decide it's a drag rather than just a touch. This also prevents
// a slight movement in a different direction to the direction
// the user intended to move being considered a drag in that direction.
// Note that the touchSlop varies on each device because of different
// pixel densities.
ViewConfiguration vc = ViewConfiguration.get(context);
int touchSlop = vc.getScaledTouchSlop();
// So we can detect changes of direction. We need to
// keep moving oldY as we use that as the reference to see if we
// are dragging up or down.
if (posY - oldY > touchSlop) {
// The drag has moved far enough up the Y axis for us to
// decide it's a drag, so set oldY to a new position just below
// the current drag position. By setting oldY just below the
// current drag position we make sure that if while dragging the
// user stops their drag and accidentally moves down just by a
// pixel or two (which is easily done even when the user thinks
// their finger isn't moving), we don't count it as a change of
// direction, so we use half the touchSlop figure as a small
// buffer to allow a small movement down before we consider it
// a change of direction.
oldY = posY - (touchSlop / 2);
} else if (posY - oldY < -touchSlop) {
// The drag has moved far enough down the Y axis for us to
// decide it's a drag, so set oldY to a new position just above
// the current drag position. This time, we set oldY just above the
// current drag position.
oldY = posY + (touchSlop / 2);
}