Search code examples
androiduiswipegesturerecognizerswipe-gesture

How to perform onClick action and onswipe operation on same view


I have a view /view group. I want to show some dialog when user swipes from left to right on that view. And when clicking/touch on that same view i need to send other activity/screen.

Its performing only clicking/touch operation. I used Gesture listener also its not working as i expected.

This is my code

 root=(LinearLayout)mView.findViewById(R.id.root_home);
        final GestureDetector gesture = new GestureDetector(getActivity(),
                new GestureDetector.SimpleOnGestureListener() {

                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }

                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                           float velocityY) {
                        //Log.i(Constants.APP_TAG, "onFling has been called!");
                        final int SWIPE_MIN_DISTANCE = 120;
                        final int SWIPE_MAX_OFF_PATH = 250;
                        final int SWIPE_THRESHOLD_VELOCITY = 200;
                        try {
                            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                                return false;
                            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                Log.i(Constants.APP_TAG, "Right to Left");


                            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                Log.i(Constants.APP_TAG, "Left to Right");


                            }
                        } catch (Exception e) {
                            // nothing
                        }
                        return super.onFling(e1, e2, velocityX, velocityY);
                    }
                });

        root.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gesture.onTouchEvent(event);
            }
        });

       root.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
            @Override
            public void onSwipeLeft() {
                // Whatever

                Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onSwipeRight() {
                // Whatever

                Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
            }
        });

        return mView;
    }

    public class OnSwipeTouchListener implements View.OnTouchListener {

        private final GestureDetector gestureDetector;

        public OnSwipeTouchListener(Context context) {
            gestureDetector = new GestureDetector(context, new GestureListener());
        }

        public void onSwipeLeft() {
        }

        public void onSwipeRight() {
        }

        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }

        private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

            private static final int SWIPE_DISTANCE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;

            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                float distanceX = e2.getX() - e1.getX();
                float distanceY = e2.getY() - e1.getY();
                if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (distanceX > 0)
                        onSwipeRight();
                    else
                        onSwipeLeft();
                    return true;
                }
                return false;
            }
        }
    }

Solution

  • If cannot manage swipes, here is a working piece of code. yourView is the view you want to attach listener to.

    yourView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
    
                    switch (event.getAction()) {
    
                        case MotionEvent.ACTION_DOWN:
                            x1 = event.getX();
                            y1 = event.getY();
                            t1 = System.currentTimeMillis();
                            return true;
                        case MotionEvent.ACTION_UP:
                            x2 = event.getX();
                            y2 = event.getY();
                            t2 = System.currentTimeMillis();
    
                            if (x1 == x2 && y1 == y2 && (t2 - t1) < CLICK_DURATION) {
                                Toast.makeText(getActivity(), "Click", Toast.LENGTH_SHORT).show();
                            } else if ((t2 - t1) >= CLICK_DURATION) {
                                Toast.makeText(getActivity(), "Long click", Toast.LENGTH_SHORT).show();
                            } else if (x1 > x2) {
                                Toast.makeText(getActivity(), "Left swipe", Toast.LENGTH_SHORT).show();
                            } else if (x2 > x1) {
                                Toast.makeText(getActivity(), "Right swipe", Toast.LENGTH_SHORT).show();
                            } 
    
    
                            return true;
                    }
    
                    return false;
                }