Fling gesture detection on grid layout

前端 未结 18 1554
遥遥无期
遥遥无期 2020-11-21 04:38

I want to get fling gesture detection working in my Android application.

What I have is a GridLayout that contains 9 ImageView

18条回答
  •  一向
    一向 (楼主)
    2020-11-21 05:39

    You can use the droidQuery library to handle flings, clicks, long clicks, and custom events. The implementation is built on my previous answer below, but droidQuery provides a slick, simple syntax:

    //global variables    private boolean isSwiping = false;
    private SwipeDetector.Direction swipeDirection = null;
    private View v;//must be instantiated before next call.
    
    //swipe-handling code
    $.with(v).swipe(new Function() {
        @Override
        public void invoke($ droidQuery, Object... params) {
            if (params[0] == SwipeDetector.Direction.START)
                isSwiping = true;
            else if (params[0] == SwipeDetector.Direction.STOP) {
                if (isSwiping) {                    isSwiping = false;
                    if (swipeDirection != null) {
                        switch(swipeDirection) {
                            case DOWN :                                //TODO: Down swipe complete, so do something
                                break;
                            case UP :
                                //TODO: Up swipe complete, so do something
                                break;
                            case LEFT :
                                //TODO: Left swipe complete, so do something
                                break;
                            case RIGHT :
                                //TODO: Right swipe complete, so do something
                                break;
                            default :                                break;
                        }
                    }                }
            }
            else {
                swipeDirection = (SwipeDetector.Direction) params[0];
            }
        }
    });
    

    Original Answer

    This answer uses a combination of components from the other answers here. It consists of the SwipeDetector class, which has an inner interface for listening for events. I also provide a RelativeLayout to show how to override a View's onTouch method to allow both swipe events and other detected events (such as clicks or long clicks).

    SwipeDetector

    package self.philbrown;
    
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    
    /**
     * Detect Swipes on a per-view basis. Based on original code by Thomas Fankhauser on StackOverflow.com,
     * with adaptations by other authors (see link).
     * @author Phil Brown
     * @see android-basic-gesture-detection
     */
    public class SwipeDetector implements View.OnTouchListener
    {
        /**
         * The minimum distance a finger must travel in order to register a swipe event.
         */
        private int minSwipeDistance;
    
        /** Maintains a reference to the first detected down touch event. */
        private float downX, downY;
    
        /** Maintains a reference to the first detected up touch event. */
        private float upX, upY;
    
        /** provides access to size and dimension contants */
        private ViewConfiguration config;
    
        /**
         * provides callbacks to a listener class for various swipe gestures.
         */
        private SwipeListener listener;
    
        public SwipeDetector(SwipeListener listener)
        {
            this.listener = listener;
        }
    
    
        /**
         * {@inheritDoc}
         */
        public boolean onTouch(View v, MotionEvent event)
        {
            if (config == null)
            {
                    config = ViewConfiguration.get(v.getContext());
                    minSwipeDistance = config.getScaledTouchSlop();
            }
    
            switch(event.getAction())
            {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                return true;
            case MotionEvent.ACTION_UP:
                upX = event.getX();
                upY = event.getY();
    
                float deltaX = downX - upX;
                float deltaY = downY - upY;
    
                // swipe horizontal?
                if(Math.abs(deltaX) > minSwipeDistance)
                {
                    // left or right
                    if (deltaX < 0)
                    {
                            if (listener != null)
                            {
                                    listener.onRightSwipe(v);
                                    return true;
                            }
                    }
                    if (deltaX > 0)
                    {
                            if (listener != null)
                            {
                                    listener.onLeftSwipe(v);
                                    return true;
                            }
                    }
                }
    
                // swipe vertical?
                if(Math.abs(deltaY) > minSwipeDistance)
                {
                    // top or down
                    if (deltaY < 0)
                    {
                            if (listener != null)
                            {
                                    listener.onDownSwipe(v);
                                    return true;
                            }
                    }
                    if (deltaY > 0)
                    {
                            if (listener != null)
                            {
                                    listener.onUpSwipe(v);
                                    return true;
                            }
                    }
                }
            }
            return false;
        }
    
        /**
         * Provides callbacks to a registered listener for swipe events in {@link SwipeDetector}
         * @author Phil Brown
         */
        public interface SwipeListener
        {
            /** Callback for registering a new swipe motion from the bottom of the view toward its top. */
            public void onUpSwipe(View v);
            /** Callback for registering a new swipe motion from the left of the view toward its right. */
            public void onRightSwipe(View v);
            /** Callback for registering a new swipe motion from the right of the view toward its left. */
            public void onLeftSwipe(View v);
            /** Callback for registering a new swipe motion from the top of the view toward its bottom. */
            public void onDownSwipe(View v);
        }
    }
    

    Swipe Interceptor View

    package self.philbrown;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.RelativeLayout;
    
    import com.npeinc.module_NPECore.model.SwipeDetector;
    import com.npeinc.module_NPECore.model.SwipeDetector.SwipeListener;
    
    /**
     * View subclass used for handling all touches (swipes and others)
     * @author Phil Brown
     */
    public class SwipeInterceptorView extends RelativeLayout
    {
        private SwipeDetector swiper = null;
    
        public void setSwipeListener(SwipeListener listener)
        {
            if (swiper == null)
                swiper = new SwipeDetector(listener);
        }
    
        public SwipeInterceptorView(Context context) {
            super(context);
        }
    
        public SwipeInterceptorView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public SwipeInterceptorView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent e)
        {
            boolean swipe = false, touch = false;
            if (swiper != null)
                swipe = swiper.onTouch(this, e);
            touch = super.onTouchEvent(e);
            return swipe || touch;
        }
    }
    

提交回复
热议问题