Search code examples
androidontouchlistenertouch-eventmotioneventandroid-touch-event

Need to be able to pinch to zoom, but not to do a double Tap in my touch listener


So I have a view under my view, that I need to pass to the pinch to zoom. BUT, if the user double taps, than I do not want to pass the double tap to my second view. Because I need the functionality that is set on a double tap to be ignored. The only problem is that that functionality is set to be called on 2 ACTION_DOWN events received from the touch listener. Now I tried to make a logic to prevent from doubletapping to work, but make the pinch to zoom work, but it still isn't perfect. IF I tap with 2 fingers, 1 in 1 place of the screen, and then the other in another place, a bit further it will get it as a double tap, and not consume the Touch, as I need. This is the code for my touchEventListener:

viewTop.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.i("","double touch event action: ===========================");
            Log.i("","double touch event test action:" + event.getPointerId(0));
            if(event.getPointerId(0) == 0) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    if (secondPressed) {
                        Log.i("", "double touch test : FIRST FINGER: CONSUMED TRUE");
                        timeLastTouch = System.currentTimeMillis();
                        return true;
                    }else {
                        Log.i("", "double touch DOWN : " + timeLastTouch + "... time passed: " + (System.currentTimeMillis() - timeLastTouch) + "..... location diff: " + (event.getX() - xLastTouch));
                        Log.i("", "double touch test XLAST : " + xLastTouch + "/" + yLastTouch + "   ... XLAST 2 : " + xLastTouch2 + "/" + yLastTouch2);
                        if (System.currentTimeMillis() - timeLastTouch < 1000 && Math.abs(event.getX() - xLastTouch) < 150 && Math.abs(event.getY() - yLastTouch) < 150) {
                            Log.i("", "double touch test TRUE DOWN");
                            secondPressed = true;
                            timeLastTouch = System.currentTimeMillis();
                            xLastTouch = event.getX();
                            yLastTouch = event.getY();
                            return true;
                        } else if (System.currentTimeMillis() - timeLastTouch < 1000 && Math.abs(event.getX() - xLastTouch2) < 150 && Math.abs(event.getY() - yLastTouch2) < 150) {
                            Log.i("", "double touch test TRUE DOWN");
                            secondPressed = true;
                            timeLastTouch = System.currentTimeMillis();
                            return true;
                        } else {
                            timeLastTouch = System.currentTimeMillis();
                            if(xLastTouch2 == -1) {
                                xLastTouch2 = event.getX();
                                yLastTouch2 = event.getY();
                            }else {
                                xLastTouch = event.getX();
                                yLastTouch = event.getY();
                            }
                            Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! X : " + event.getX() + "/" + event.getY() + ".... TIME: " + (System.currentTimeMillis() - timeLastTouch));
                            Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DIFF LAST TOUCH: " + Math.abs(event.getX() - xLastTouch) + "/" + Math.abs(event.getY() - yLastTouch));
                            Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DIFF LAST TOUCH2: " + Math.abs(event.getX() - xLastTouch2) + "/" + Math.abs(event.getY() - yLastTouch2));
                            return false;
                        }
                    }
                } else if (event.getAction() == MotionEvent.ACTION_UP) {
                    handlerTouch.removeCallbacksAndMessages(null);
                    Log.i("", "double touch test FALSE UP");
                    timeLastTouch = System.currentTimeMillis();
                    handlerTouch.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            resetTouches();
                            Log.i("", "double touch test : SECOND PRESSED BECOMES FALSE");
                        }
                    }, 300);
                    return true;
                } else {
                    timeLastTouch = System.currentTimeMillis();
                    xLastTouch = event.getX();
                    yLastTouch = event.getY();
                    Log.i("", "double touch ELSE FALSE");
                    return false;
                }
            }else if(event.getPointerId(0) == 1){
                timeLastTouch = System.currentTimeMillis();
                if(event.getAction() == MotionEvent.ACTION_DOWN) {
                    xLastTouch2 = event.getX();
                    yLastTouch2 = event.getY();
                    secondPressed = true;
                    return false;
                }else if(event.getAction() == MotionEvent.ACTION_UP){
                    Log.i("","double touch test : SECONDARY FINGER: SECOND PRESSED BECOMES FALSE");
                    handlerTouch.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            resetTouches();
                            Log.i("", "double touch test : SECOND PRESSED BECOMES FALSE");
                        }
                    }, 300);
                }else {
                    Log.i("","double touch test : SECONDARY FINGER: SECOND PRESSED BECOMES TRUE");
                    secondPressed = true;
                }
                return false;
            }else {
                timeLastTouch = System.currentTimeMillis();
                secondPressed = true;
                return false;
            }
        }
    });

Where resetTouches is:

    private void resetTouches() {
    xLastTouch = -1f;
    yLastTouch = -1f;
    xLastTouch2 = -1f;
    yLastTouch2 = -1f;
    secondPressed = false;
}

Now I'm kinda blocked here, and don't know what or how to change in order to prevent the double tap to work. Is there by any change any implementation of this that might be easier? What could I change to improve on this?


Solution

  • This did it for me:

    final ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(InCallActivity.this, new ScaleGestureDetector.OnScaleGestureListener() {
            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
                Log.i("", "double touch test2 onScaleEnd: " + detector.getScaleFactor());
                app.TouchEvent(0, 1, (int) xFinger1, (int) yFinger1);
                if (xFinger2 != 0) {
                    app.TouchEvent(1, 1, (int) xFinger2, (int) yFinger2);
                } else scale(1, (int) (yFinger1));
            }
            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                Log.i("", "double touch test2 onScaleBegin: " + detector.getScaleFactor());
                app.TouchEvent(0, 0, (int) xFinger1, (int) yFinger1);
                if (xFinger2 != 0) {
                    app.TouchEvent(1, 0, (int) xFinger2, (int) yFinger2);
                } else app.TouchEvent(1, 0, (int) xFinger1, (int) yFinger1);
                return true;
            }
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                Log.i("", "double touch test2 zoom ongoing, scale: " + detector.getScaleFactor());
                app.TouchEvent(0, 2, (int) xFinger1, (int) yFinger1);
                if (xFinger2 != 0) {
                    app.TouchEvent(1, 2, (int) xFinger2, (int) yFinger2);
                } else {
                    scaleValue = detector.getScaleFactor();
                    scale(2, (int) (yFinger1));
                }
                return false;
            }
        });
        viewTop.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("", "double touch test2 ON TOUCH: " + event.getPointerId(0) + "x/y: " + event.getX() + "/" + event.getY());
                xFinger1 = event.getX(0);
                yFinger1 = event.getY(0);
                try {
                    xFinger2 = event.getX(1);
                    yFinger2 = event.getY(1);
                    mScaleDetector.onTouchEvent(event);
                } catch (Exception e) {
                    return logicFor1Finger(event, e);
                }
                return true;
            }
        });