views:

263

answers:

2

Im trying to swipe left and right on a listview and get the viewflipper to swtich. Just like the remeberthemilk app and the default news and weather app on the nexus one (Swiping through news topics). Using various tutorials ive found , i came across on one stackoverflow that shows how to implement a swipe gesture

    class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return true;
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {


            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                viewFlipper.setInAnimation(slideRightIn);
                viewFlipper.setOutAnimation(slideRightOut);
                viewFlipper.showPrevious();
            }
        } catch (Exception e) {
            // nothing
        }
        return true;
    }
}

And i got this working by doing

  lstView.setOnTouchListener(gestureListener);

However sometimes what would happen is the listview setOnItemClickListener would be fired when the person is swiping. How do i prevent this from happening, and only get the setOnItemClickListener fired when the user actually clicks on it list item and not just swiping on it.

Thanks, Faisal Abid

A: 

I think you cant do alot about it, other than playing with your constants in your code, so that its better decidable if the user clicked or wants to swipe. For example I did it the following way in my code (i used touch event but the principle should be similar):

 @Override
    public boolean onTouch(View view, MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            {
                downXValue = event.getX();
                downTime = event.getEventTime();
                break;
            }

            case MotionEvent.ACTION_UP:
            {
                float currentX = event.getX();
                long currentTime = event.getEventTime();
                float difference = Math.abs(downXValue - currentX);
                long time = currentTime - downTime;

                Log.i("Touch Event:",  "Distance: " + difference + "px Time: " + time + "ms");

                if ( (downXValue < currentX) && (time > 50) && (difference > 50) ) {
                    showPrevious();
                }

                if ( (downXValue > currentX) && (time > 50) && (difference > 50) ) {
                    showNext();
                }
                break;
            }
        }

As you can see i put a Log output there. So i just tested the app and every time i tried to flip or click, the Log told me how long i pressed and how big the difference was. So i adjusted my values in the if condition until it worked in almost all cases

Roflcoptr
A: 

Well one way I found is instead of relying on, onItemClick, I implemented

        @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        // TODO Auto-generated method stub
            Log.e("Item Click","Item Click");
        return super.onSingleTapConfirmed(e);
    }

Inside SimpleOnGestureListener and it seems as if it works

Faisal Abid