Deepak
Deepak

Reputation: 1258

Implement both swipe and longclick on list item?

I need to implement both Longclick and Left & right swipe on a list view and get the listitem on which the action was performed. This method seemed really promising. Problems: 1.ACTION_MOVE is fired only once at the start so the diff is really minimal 2.If i use a default in the switch i get the last location but onClick or onLongClick is never fired. Here is what i tried.. Is it possible to fire a fake ACTION to cause itemClick/itemlongclick to execute.

public boolean onTouch(View v, MotionEvent event) 
    {
        switch (event.getAction()) 
        {
        case MotionEvent.ACTION_DOWN: 
            downX = event.getX();
            downY = event.getY();
            mSwipeDetected = Action.NONE;
            Log.i("MyTags","Down Event");
            Log.i("MyTags",String.valueOf(downX)+","+String.valueOf(downY));
            return false; // allow other events like Click to be processed
        case MotionEvent.ACTION_MOVE: 
            upX = event.getX();
            upY = event.getY();
            Log.i("MyTags","Move Event");
            Log.i("MyTags",String.valueOf(upX)+","+String.valueOf(upY));
            moveEnabled=true;
            return false;
        case MotionEvent.ACTION_UP:
            upX = event.getX();
            upY = event.getY();
            Log.i("MyTags","UP Event");
            Log.i("MyTags",String.valueOf(upX)+","+String.valueOf(upY));
            return false;
        default:
            upX = event.getX();
            upY = event.getY();
            Log.i("MyTags","Default Event");
            Log.i("MyTags",String.valueOf(upX)+","+String.valueOf(upY));
            if(moveEnabled)
            {
                diffX=downX-upX;
                diffY=downY-upY;
                abs_X=Math.abs(diffX);
                abs_Y=Math.abs(diffY);

                moveEnabled=false;
                if((abs_X>abs_Y)&(abs_X>MINIMUM_X))
                {
                    if(diffX>0)
                    {
                        mSwipeDetected=Action.LEFT;
                        Log.i("MyTags","Left Swipe");
                        event.setAction(MotionEvent.ACTION_UP);
                        return false;
                    }
                    else if(diffX<0)
                    {
                        mSwipeDetected=Action.RIGHT;
                        Log.i("MyTags","Right Swipe");
                        event.setAction(MotionEvent.ACTION_UP);
                        return false;
                    }
                }
            }
            return false;
        }

    }

Upvotes: 0

Views: 757

Answers (1)

Deepak
Deepak

Reputation: 1258

I kind of used a hack to fix my issue.What happens is since the events are consumed, i never get the result in the onitemclick event. What i have done is to fire my own Down and Up events once a swipe action is detected and during those fake events i return false so that its passed down to the itemclick listener. We need to be a bit careful here as the event seems to read from the result 2 times , for this i turn the listener on and off , there by containing the output.

ACTION_MOVE:
 //when swipe is detected fire a fake down event
 event.setAction(MotionEvent.ACTION_DOWN);
 v.dispatchTouchEvent(event);
ACTION_DOWN:
  if(fake down event)
     //set some flags & dispatch fake event
     event.setAction(MotionEvent.ACTION_UP);
     v.dispatchTouchEvent(event);
     return false
   else do regular handling
ACTION_UP:
    if fake down event
       dispatch fake up event
    else ..

here 'v' is the view on which the event has to be fired , in my case its the listview. Since we dont have it right-off it has to be passed in through the constructor of the swipeDetector class. As follows..

ListView v;
SwipeDetector(ListView lv)
{
    this.v=lv;
}

Upvotes: 1

Related Questions