docs: public boolean onTouchEvent(MotionEvent event) {
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          mIsCapturingGesture = true;
          mIsClickCandidate = true;
          mActionDownTime = event.getEventTime();
          mActionDownX = event.getX();
          mActionDownY = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          if (Math.abs(event.getX() - mActionDownX) > mSingleTapSlopPx ||
              Math.abs(event.getY() - mActionDownY) > mSingleTapSlopPx) {
            mIsClickCandidate = false;
          }
          break;
        case MotionEvent.ACTION_CANCEL:
          mIsCapturingGesture = false;
          mIsClickCandidate = false;
          break;
        case MotionEvent.ACTION_UP:
          mIsCapturingGesture = false;
          if (Math.abs(event.getX() - mActionDownX) > mSingleTapSlopPx ||
              Math.abs(event.getY() - mActionDownY) > mSingleTapSlopPx) {
            mIsClickCandidate = false;
          }
          if (mIsClickCandidate) {
            if (event.getEventTime() - mActionDownTime <= ViewConfiguration.getLongPressTimeout()) {
              if (mClickListener != null) {
                mClickListener.onClick();
              }
            } else {
              // long click, not handled
            }
          }
          mIsClickCandidate = false;
          break;
      }
      return true;
    }