Android: MotionEvent ACTION_UP doesn't trigger after ACTION_CANCEL

766 Views Asked by At

I'm making video stories like instagram. So I met a problem with gestures.

The problem is that ACTION_CANCEL handled when I'm doing these moves and ACTION_UP doesn't call if I raise my finger

  1. I'm in 1st page of ViewPager and I swipe left->right fastly (my finger still on screen)
  2. I'm in the middle of ViewPager and I swipe left->right or right->left, but not finishing the swipe and I'm still in the current page and my finger on screen
  3. I'm moving chaosly on screen (my finger still on screen)

So if I raise my finger after ACTION_CANCEL called, my video stay in "PAUSE" state

Finally, question is: How I can handle Action_Up event after Action_Cancel?

override fun onTouch(v: View?, event: MotionEvent?): Boolean {
    if (gestureDetector?.onTouchEvent(event) == true) return true

    when (event?.actionMasked) {
        MotionEvent.ACTION_DOWN -> {
            viewModel.videoPause()
        }
        MotionEvent.ACTION_UP -> {
            viewModel.videoResume()
        }
        MotionEvent.ACTION_CANCEL -> {
            // Handles when doing these moves and ACTION_UP doesn't call if I raise my finger
            // 1. I'm in 1st page of ViewPager and I swipe left->right fastly (my finger still on screen)
            // 2. I'm in the middle of ViewPager and I swipe left->right or right->left, but not finishing the swipe
            // and I'm still in the current page and my finger on screen
            // 3. I'm moving chaosly on screen (my finger still on screen)


            // So if I raise my finger after ACTION_CANCEL called, my video stay in "PAUSE" state
        }
        else -> { }
    }

    return true
}

user stories 1st page user stories swipe

2

There are 2 best solutions below

4
cactustictacs On BEST ANSWER

You don't get an ACTION_UP after an ACTION_CANCEL:

ACTION_CANCEL

public static final int ACTION_CANCEL

Constant for getActionMasked(): The current gesture has been aborted. You will not receive any more points in it. You should treat this as an up event, but not perform any action that you normally would.

0
Mustafa Aslan On

Actually there is a way to do this.

@Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        performClick();
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                float y = event.getY();
                Log.d("coordinates: ","x : "+String.valueOf(x)+"y : " + String.valueOf(y));
                break;
            case MotionEvent.ACTION_UP:
                Log.d("action","up")
        }
        return true;
    }

Add this to your parent View. This will show you the location of your finger whenever it moves. And (I don't know how) but when you hold your finger, it also triggers the action up. So whenever the action up is triggered, you'll know that the user held his finger, or whenever the x or y coordinates are outside of your parent view, you can treat it as if the user held his finger. (I got this idea from a canvas question [https://stackoverflow.com/questions/21846584/android-canvas-draw-by-finger])