1

I'm using motion event, action_down, action_move etc, to detect when there is no finger movement but the finger is still on the screen. For instance, the user moves in a vertical line from top of the screen to the bottom and then stops movement without lifting the finger. How do I detect when there is no movement but the finger is still on the screen after the drag/swipe?

EDIT: What I'm trying to do is count every time I change direction of movement in a vertical direction. And to do that I'm trying to detect when I stop movement against the change of movement. For instance, I move down the screen and then move back up, that counts as two counts. Here is my code, please don't provide me with code as a direct answer but hints or clues so that I can try and figure it out myself (my code might look a bit confusing, I'm just trying out different things):

@Override public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:

        oldX = event.getX();
        oldY = event.getY();

        oldSpeedY = System.currentTimeMillis();
        break;

    case MotionEvent.ACTION_MOVE:
        posY = event.getY();
        posSpeedY = System.currentTimeMillis();

        float timeElapsed = (posSpeedY - oldSpeedY) / 1000;
        float diffSpeed = posSpeedY - oldSpeedY;
        if (changeOfMovement(posY, oldY)) {
        //if (diffSpeed == 0)
            count += 1;


        }

        break;

    case MotionEvent.ACTION_UP:

        // count seconds here
        break;

    }

    Toast.makeText(getApplicationContext(), "Swipe: " + count,
            Toast.LENGTH_SHORT).show();

    return false;

}

public boolean changeOfMovement(float posY, float oldY) {

    int newY = Math.round(posY);
    double distance = Math.abs(newY - oldY);

    oldY = newY;
    //float speed = (float) (distance / time);
    //if (distance < 25)
        //return false;
    //if (speed == 0)

        //return true;

    if (distance < 25)

        return true;

    return false;
}
Kaal
  • 111
  • 1
  • 10
  • Please post the code you have so far, SO is not here to provide you with code from scratch upon request. – LBes Jun 24 '15 at 11:51

3 Answers3

0

The finger touches the screen until you receive either of the MotionEvent actions ACTION_UP or ACTION_CANCEL

drewi
  • 690
  • 7
  • 26
  • Quick question, if I stop movement without lifting my finger off the screen does that call action_up or does action_up only refer to when the user lifts the finger off the screen? – Kaal Jun 24 '15 at 13:34
  • ACTION_UP is only when lifting the finger off the screen – drewi Jun 24 '15 at 13:37
  • Thanks. I have another question, in ACTION_MOVE if I get the current position with e.g. posY = event.getY(); and I stop the movement of my finger, while dragging it down the screen, without lifting my finger off the screen, is there a way to detect that I have stopped movement? Before I go off dragging my finger towards another direction like going back up. – Kaal Jun 24 '15 at 14:03
  • There is no method for that, it's up to you to keep track of that. For example use a boolean to keep track of if a finger is touching the screen, or if you want to know the time since the last movement then store the timestamp of the event in a long – drewi Jun 24 '15 at 14:26
  • I've tried that but what I really need is to detect the change in direction or when there is a short pause in System.currentTimeMillis() in the ACTION_MOVE, which will occur when I do move in a different direction. For instance, I move my finger down and then up, before I move up there must be some pause in the time that I can get, so I can count that? – Kaal Jun 24 '15 at 17:37
  • @Kaal Please check my answer below :) – Mohammed AlBanna Jan 21 '16 at 22:16
0

The ACTION_DOWN Event is still valid until the finger is lifted from the screen or you can wait till a ACTION_UP Event is detected

chiragjn
  • 764
  • 11
  • 31
0

I'm not sure if my situation is like yours, but mine I was want to detect if the user stopped moving inside circle within one second and starts moving again, by comparing between last two currentTimeMillis.

So, what I've done is I initialized fixed ArrayList to save the last two times in move event:

public class FixedArrayList extends ArrayList {
    int fixedSize = 10;

    public FixedArrayList(){}

    public FixedArrayList(int fixedSize){
        this.fixedSize = fixedSize;
    }

    @SuppressWarnings("All")
    public void addItem(Object object){
        if(size() < fixedSize){
            add(object);
        } else{
            remove(0);
            add(object);
        }
    }
}

Now, I've initialized my new class with fixed 2 items to be saved:

    FixedArrayList savedLastMove = new FixedArrayList(2); 
    int secondsToWait = 1;
    public boolean onTouchEvent(MotionEvent event) {
    int action = MotionEventCompat.getActionMasked(event);
    switch (action) {
        case (MotionEvent.ACTION_MOVE):
            currentSystemTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
            savedLastMove.addItem(currentSystemTime);
            if(savedLastMove.size() >= 2 && ((long)savedLastMove.get(1) - (long)savedLastMove.get(0)) >= secondsToWait){
               //Do what you want after secondsToWait
            }
        return true;
    }

I hope that will help! Because it solved my problem.

Mohammed AlBanna
  • 2,350
  • 22
  • 25