Search code examples
androidandroid-gallery

Android Gallery Flipping issue


I have a Gallery of views that contain a TextView Label and then a listview below that. It works excellent except that in order to get it to flip from element to element, the user has to touch either above the listview (near the label) and fling or in between gallery objects. Sometimes below the listview works too.But I really want to be able to fling while touching the listview too because it takes up a majority of the screen. How can this be done? What code do you need to see?


Solution

  • I had a similar problem and solved this by overriding the Gallery and implementing the onInterceptTouchEvent to ensure that move events are intercepted by the Gallery, and all other events are handled normally.

    Returning true in the onInterceptTouchEvent causes all following touch events in this touch sequence to be sent to this view, false leaves the event for it's children. TouchSlop is needed as when doing a click there is sometimes a small amount of movement.

    Would love to claim this as my own idea, but got the basics of the code from the default Android Launcher code.

    public class MyGallery extends Gallery{
    
    private MotionEvent downEvent;
    private int touchSlop;
    private float lastMotionY;
    private float lastMotionX;
    
    public MyGallery(Context context) {
        super(context);
        initTouchSlop();
    }
    
    private void initTouchSlop() {
        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        touchSlop = configuration.getScaledTouchSlop();
    }
    
    @Override public boolean onInterceptTouchEvent(MotionEvent ev) {
        final float x = ev.getX();
        final float y = ev.getY();
    
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_MOVE: {
                final int xDiff = (int) Math.abs(x - lastMotionX);
                final int yDiff = (int) Math.abs(y - lastMotionY);
    
                // have we moved enough to consider this a scroll
                if (xDiff > touchSlop || yDiff > touchSlop) {
                    // this is the event we want, but we need to resend the Down event as this could have been consumed by a child
                    Log.d(TAG, "Move event detected: Start intercepting touch events");
                    if (downEvent != null) this.onTouchEvent(downEvent);
                    downEvent = null;
                    return true;
                }
                return false;
            }
            case MotionEvent.ACTION_DOWN: {
                // need to save the on down event incase this is going to be a scroll
                downEvent = MotionEvent.obtain(ev);
                lastMotionX = x;
                lastMotionY = y;
                return false;
            }
            default: {
                // if this is not a down or scroll event then it is not for us
                downEvent = null;
                return false;
            }
        }
    }