How to prevent a ViewGroup from receiving ACTION_CANCEL events?

27 views Asked by At

I am at a total loss here. I have read the previous questions regarding ACTION_CANCEL and checked the docs. But none helps my situation.

Here is a simple example to demonstrate what I am after. I have a custom ViewGroup (an inner class) set as the content of an activity:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(GestureView(applicationContext))
    }


    private class GestureView(context: Context) : ViewGroup(context) {

        init {
            setBackgroundColor(Color.BLUE)
        }

        override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

        }

        override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
            Log.d("GestureView", "(onInterceptTouchEvent) " +
                    MotionEvent.actionToString(ev!!.actionMasked)
            )
            return true
        }

        @SuppressLint("ClickableViewAccessibility")
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            Log.d("GestureView", "(onTouchEvent) " +
                    MotionEvent.actionToString(event!!.actionMasked)
            )
            return true
        }

    }
}

Now, I am interested in a specific motion, where one finger is kept on the screen, and the other is moving. But when I try that, I often get a series of events like these:

(onInterceptTouchEvent) ACTION_DOWN
(onTouchEvent) ACTION_DOWN
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_POINTER_DOWN(0)
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_CANCEL
(onInterceptTouchEvent) ACTION_DOWN
(onTouchEvent) ACTION_DOWN
(onTouchEvent) ACTION_POINTER_DOWN(0)
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_POINTER_UP(0)
(onTouchEvent) ACTION_MOVE
(onTouchEvent) ACTION_CANCEL

With ACTION_CANCEL, no further events are received in this motion, and I need to lift all the fingers to start over.

Why does this cancelation happen, and how can I prevent it (continue with the gesture)?

What I have tried and got the same results:

  • Returning true or false in onInterceptTouchEvent().
  • Using dispatchTouchEvent() instead of onInterceptTouchEvent().
  • Adding requestDisallowInterceptTouchEvent(true) (as suggested here) doesn't help since there is no parent view that intercepts.
0

There are 0 answers