Detect touch event when onInterceptTouchEvent() used

Adrian Olar picture Adrian Olar · Aug 5, 2013 · Viewed 7.7k times · Source

I am asking this rather complex question hoping that i would get an idea from you.

Here is the thing: I have created a custom list view class, the one above:

public class FolderListView extends ListView {

    private float xDistance, yDistance, lastX, lastY;
    private int folder_index;
    private FolderViewInterface openFolder;

    // private boolean swiping = false;

    // If built programmatically
    public FolderListView(Context context) {
        super(context);
    }

    // This example uses this method since being built from XML
    public FolderListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // Build from XML layout
    public FolderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

        case MotionEvent.ACTION_UP:
            // if (swiping == false) {

            //if (xDistance > yDistance)
            //  return false;
        //  else {
                folder_index = pointToPosition((int) lastX, (int) lastY);
            //  Toast.makeText(getContext(),
            //          "You pressed a folder with index: " + folder_index,
            //          Toast.LENGTH_SHORT).show();
        //  }
            HomeScreenFragment f = new HomeScreenFragment();
            openFolder = (FolderViewInterface) f;
            openFolder.onFolderOpened(folder_index);
            // }
            // swiping = false;
            break;

        case MotionEvent.ACTION_DOWN:
            // swiping = false;
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            // swiping = true;
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if (xDistance > yDistance)
                return false;
        }

        return super.onInterceptTouchEvent(ev);

    }

}

thing is here i am looking to properly detect the touch event. I want on touch to open the other fragment, but right now the fragment is opened both on touch and on swipe.

I have used the onInterceptTouchEvent because the elements of my list are viewpagers and they were not behaving properly when scrolling.

I need some kind of logic here to detect the swiping and not perform this part:

HomeScreenFragment f = new HomeScreenFragment();
            openFolder = (FolderViewInterface) f;
            openFolder.onFolderOpened(folder_index);

Only if the event is a touch event, not a swipe one.

Any kind of suggestion/help is highly appreciated, please let me know if you need any more details.

Thanks!

Answer

Girish Nair picture Girish Nair · Aug 5, 2013

I am taking time 125 based on PRESSED_STATE_DURATION

Try this

//Declare as instance variables
int oldX,oldY,newX,newY;
//State the minimum distance of swipe that you forgive the user for ;)
int distance = 10;
int time = 125;
boolean cancel = false;
case MotionEvent.ACTION_DOWN:
cancel = false;
//Get x and y of touch
oldX = ev.getX();
oldY = ev.getY();
startActionTimer();

case MotionEvent.ACTION_MOVE:
//Get x and y of touch
newX = ev.getX();
newY = ev.getY();

case MotionEvent.ACTION_UP:
cancel = true;

private void startActionTimer(){
        //time is pressed state duration
          new CountDownTimer(time, time) {
             public void onTick(long millisUntilFinished) {}

             public void onFinish() {
                //Time to do our action!!!
                // please consider
                if((Math.abs(newX - oldX )< distance) && (Math.abs(newY - oldY ) <distance)){
                    if(cancel == false){
                    // Now its a touch so do your action
                    }
                }
             }
          }.start();
     }

NOTE: Please use all the variables as class variables(instance variables) to avoid problems. Because sometimes i get weird situations where values are not updated properly

OR

Why don't you try the gesture detection

and override the onSingleTapUp method