Android: How to handle right to left swipe gestures

前端 未结 22 1165
日久生厌
日久生厌 2020-11-21 06:18

I want my app to recognize when a user swipes from right to left on the phone screen.

How to do this?

相关标签:
22条回答
  • 2020-11-21 07:05

    This question was asked many years ago. Now, there is a better solution: SmartSwipe: https://github.com/luckybilly/SmartSwipe

    code looks like this:

    SmartSwipe.wrap(contentView)
            .addConsumer(new StayConsumer()) //contentView stay while swiping with StayConsumer
            .enableAllDirections() //enable directions as needed
            .addListener(new SimpleSwipeListener() {
                @Override
                public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                    //direction: 
                    //  1: left
                    //  2: right
                    //  4: top
                    //  8: bottom
                }
            })
    ;
    
    0 讨论(0)
  • 2020-11-21 07:06
    public class TranslatorSwipeTouch implements OnTouchListener
    {
       private String TAG="TranslatorSwipeTouch";
    
       @SuppressWarnings("deprecation")
       private GestureDetector detector=new GestureDetector(new TranslatorGestureListener());
    
       @Override
       public boolean onTouch(View view, MotionEvent event)
       {
         return detector.onTouchEvent(event);
       }
    
    private class TranslatorGestureListener extends SimpleOnGestureListener 
    {
        private final int GESTURE_THRESHOULD=100;
        private final int GESTURE_VELOCITY_THRESHOULD=100;
    
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    
        @Override
        public boolean onFling(MotionEvent event1,MotionEvent event2,float velocityx,float velocityy)
        {
            try
            {
                float diffx=event2.getX()-event1.getX();
                float diffy=event2.getY()-event1.getY();
    
                if(Math.abs(diffx)>Math.abs(diffy))
                {
                    if(Math.abs(diffx)>GESTURE_THRESHOULD && Math.abs(velocityx)>GESTURE_VELOCITY_THRESHOULD)
                    {
                        if(diffx>0)
                        {
                            onSwipeRight();
                        }
                        else
                        {
                            onSwipeLeft();
                        }
                    }
                }
                else
                {
                    if(Math.abs(diffy)>GESTURE_THRESHOULD && Math.abs(velocityy)>GESTURE_VELOCITY_THRESHOULD)
                    {
                        if(diffy>0)
                        {
                             onSwipeBottom();
                        }
                        else
                        {
                            onSwipeTop();
                        }
                    }
                }
            }
            catch(Exception e)
            {
                Log.d(TAG, ""+e.getMessage());
            }
            return false;           
        }
    
        public void onSwipeRight()
        {
            //Toast.makeText(this.getClass().get, "swipe right", Toast.LENGTH_SHORT).show();
            Log.i(TAG, "Right");
        }
        public void onSwipeLeft()
        {
            Log.i(TAG, "Left");
            //Toast.makeText(MyActivity.this, "swipe left", Toast.LENGTH_SHORT).show();
        }
    
        public void onSwipeTop()
        {
            Log.i(TAG, "Top");
            //Toast.makeText(MyActivity.this, "swipe top", Toast.LENGTH_SHORT).show();
        }
    
        public void onSwipeBottom()
        {
            Log.i(TAG, "Bottom");
            //Toast.makeText(MyActivity.this, "swipe bottom", Toast.LENGTH_SHORT).show();
        }   
    
      }
    
     }
    
    0 讨论(0)
  • 2020-11-21 07:07

    If you also need to process click events here some modifications:

    public class OnSwipeTouchListener implements OnTouchListener {
    
        private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
    
        public boolean onTouch(final View v, final MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    
        private final class GestureListener extends SimpleOnGestureListener {
    
            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;
    
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                boolean result = false;
                try {
                    float diffY = e2.getY() - e1.getY();
                    float diffX = e2.getX() - e1.getX();
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                result = onSwipeRight();
                            } else {
                                result = onSwipeLeft();
                            }
                        }
                    } else {
                        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffY > 0) {
                                result = onSwipeBottom();
                            } else {
                                result = onSwipeTop();
                            }
                        }
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
        }
    
        public boolean onSwipeRight() {
            return false;
        }
    
        public boolean onSwipeLeft() {
            return false;
        }
    
        public boolean onSwipeTop() {
            return false;
        }
    
        public boolean onSwipeBottom() {
            return false;
        }
    }
    

    And sample usage:

        background.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                toggleSomething();
            }
        });
        background.setOnTouchListener(new OnSwipeTouchListener() {
            public boolean onSwipeTop() {
                Toast.makeText(MainActivity.this, "top", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeRight() {
                Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeLeft() {
                Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeBottom() {
                Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    
    0 讨论(0)
  • 2020-11-21 07:12

    I know its a bit late since 2012 but I hope it will help someone since I think it's a shorter and cleaner code than most of the answers:

    view.setOnTouchListener((v, event) -> {
            
    int action = MotionEventCompat.getActionMasked(event);
    
    switch(action) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            return true;
    
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            return true;
    
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            return true;
    
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            return true;
    
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
                    "of current screen element");
            return true;
    
        default :
            return super.onTouchEvent(event);
    }
        });
    

    of course you can leave only the relevant gestures to you.

    src: https://developer.android.com/training/gestures/detector

    0 讨论(0)
  • 2020-11-21 07:13

    Expanding on Mirek's answer, for the case when you want to use the swipe gestures inside a scroll view. By default the touch listener for the scroll view get disabled and therefore scroll action does not happen. In order to fix this you need to override the dispatchTouchEvent method of the Activity and return the inherited version of this method after you're done with your own listener.

    In order to do a few modifications to Mirek's code: I add a getter for the gestureDetector in the OnSwipeTouchListener.

    public GestureDetector getGestureDetector(){
        return  gestureDetector;
    }
    

    Declare the OnSwipeTouchListener inside the Activity as a class-wide field.

    OnSwipeTouchListener onSwipeTouchListener;
    

    Modify the usage code accordingly:

    onSwipeTouchListener = new OnSwipeTouchListener(MyActivity.this) {
        public void onSwipeTop() {
            Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
        }
        public void onSwipeRight() {
            Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
        }
        public void onSwipeLeft() {
            Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
        }
        public void onSwipeBottom() {
            Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
        }
    });
    
    imageView.setOnTouchListener(onSwipeTouchListener);
    

    And override the dispatchTouchEvent method inside Activity:

    @Override
        public boolean dispatchTouchEvent(MotionEvent ev){
            swipeListener.getGestureDetector().onTouchEvent(ev); 
                return super.dispatchTouchEvent(ev);   
        }
    

    Now both scroll and swipe actions should work.

    0 讨论(0)
  • 2020-11-21 07:13

    Kotlin version of @Mirek Rusin is here:

    OnSwipeTouchListener.kt :

    open class OnSwipeTouchListener(ctx: Context) : OnTouchListener {
    
        private val gestureDetector: GestureDetector
    
        companion object {
    
            private val SWIPE_THRESHOLD = 100
            private val SWIPE_VELOCITY_THRESHOLD = 100
        }
    
        init {
            gestureDetector = GestureDetector(ctx, GestureListener())
        }
    
        override fun onTouch(v: View, event: MotionEvent): Boolean {
            return gestureDetector.onTouchEvent(event)
        }
    
        private inner class GestureListener : SimpleOnGestureListener() {
    
    
            override fun onDown(e: MotionEvent): Boolean {
                return true
            }
    
            override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
                var result = false
                try {
                    val diffY = e2.y - e1.y
                    val diffX = e2.x - e1.x
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                onSwipeRight()
                            } else {
                                onSwipeLeft()
                            }
                            result = true
                        }
                    } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom()
                        } else {
                            onSwipeTop()
                        }
                        result = true
                    }
                } catch (exception: Exception) {
                    exception.printStackTrace()
                }
    
                return result
            }
    
    
        }
    
        open fun onSwipeRight() {}
    
        open fun onSwipeLeft() {}
    
        open fun onSwipeTop() {}
    
        open fun onSwipeBottom() {}
    }
    

    Usage:

    view.setOnTouchListener(object : OnSwipeTouchListener(context) {
    
        override fun onSwipeTop() {
            super.onSwipeTop()
        }
    
        override fun onSwipeBottom() {
            super.onSwipeBottom()
        }
    
        override fun onSwipeLeft() {
            super.onSwipeLeft()
        }
    
        override fun onSwipeRight() {
            super.onSwipeRight()
        }
    })
    

    the open keyword was the point for me...

    0 讨论(0)
提交回复
热议问题