Maclaren
Maclaren

Reputation: 289

Android ListView onTouch Swipe

I am trying to make an inbox like swipe to select multiple items in a list view. I am able to show a view under the main view and am able to drag the views as well. The problem is trying to get onTouch and onItemClickListener to work together.

1: If i return true in the switch case during ACTION_DOWN the onItemClickListener stops working. If i return false then i can't drag the view, but onItemClickListener is working.

2: While dragging the view the listView is still able to scroll, which makes the onTouch go to ACTION_CANCLE

I am attaching the onTouchListener to the view in the getView() method of the adapter like so:

root.setOnTouchListener(new MySwipeListener);

    @Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            return false;
        }
        case MotionEvent.ACTION_MOVE: {
            upX = event.getX();
            float deltaX = downX - upX;
            if (Math.abs(deltaX) > MIN_LOCK_DISTANCE && listView != null && !motionInterceptDisallowed) {
                listView.onInterceptTouchEvent(event);
                listView.requestDisallowInterceptTouchEvent(true);
                motionInterceptDisallowed = true;
                listView.requestDisallowInterceptTouchEvent(true);
            }
            if (deltaX > 0) {
                holder.viewLeft.setVisibility(View.GONE);
            } else {
                // if first swiped left and then swiped right
                holder.viewLeft.setVisibility(View.VISIBLE);
            }
            //holder.mainView.setTranslationX(-(int)deltaX);
            if(deltaX < 0) {
                holder.mainView.setTranslationX(-(int) deltaX);
            }
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            float deltaX = upX - downX;
            if (Math.abs(deltaX) > MIN_DISTANCE) {
                holder.mainView.setTranslationX(200);
            } else {
                holder.mainView.setTranslationX(0);
            }
            if (listView != null) {
                listView.requestDisallowInterceptTouchEvent(false);
                motionInterceptDisallowed = false;
            }
            holder.viewLeft.setVisibility(View.VISIBLE);
            return false;
        }
        case MotionEvent.ACTION_CANCEL:{
            holder.viewLeft.setVisibility(View.VISIBLE);
            holder.mainView.setTranslationX(0);
            return false;
        }

    }
    return false;

}

Upvotes: 1

Views: 296

Answers (1)

Anand Makwana
Anand Makwana

Reputation: 51

Please use GestureDetector like below,

private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 120;

        @Override
        public boolean onDown(MotionEvent e) {
            setX((int) e.getX());
            setY((int) e.getY());
            return true;
        }

        @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) {
                            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();
            }

            Utils.log("onfling", "val Y:" + velocityY);
            return result;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            // TODO Auto-generated method stub
            if (gestureInterface != null && doubleTap) {
                gestureInterface.onDoubleTap();
                return true;
            }
            return false;
        }

    }

Upvotes: 1

Related Questions