Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Touch Events - onInterceptTouchEvent and onTouchEvent

I want to be able to swipe anywhere on the screen to call a certain function. But I also have Buttons in Linear Layouts that I want to be able to click on. If I swipe on a Button I want onInterceptTouchEvent to Intercept the call to the Button's onTouchEvent and perform a swipe action. And if I simply click on a Button I do not want the onInterceptTouchEvent to be called. Rather, I want the Button's onTouchEvent to be called and perform a Button click

But I get errors when I try implementing onInterceptTouchEvent.

Here is my code:

public class Game extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.game_activity);

   //other code....
}
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            swipeScreen(); //if action recognized as swipe then swipe
            break;
        case MotionEvent.ACTION_MOVE:
            float x = event.getX();
            float y = event.getY();
            float xDelta = Math.abs(x - mLastX);
            float yDelta = Math.abs(y - mLastY);

            if (yDelta > xDelta) {
                return true;
            }
            break;
    }

    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    ButtonOnClick(); //if not a swipe, then button click
    return true;
}

First the error says: The method onInterceptTouchEvent(MotionEvent) of type Game must override or implement a supertype method

Then instead of return true I change the code to:return super.onInterceptTouchEvent(event) but then I get an error saying: The method onInterceptTouchEvent(MotionEvent) is undefined for the type Activity

Can someone please help?

like image 949
user2456977 Avatar asked Dec 10 '14 16:12

user2456977


1 Answers

Note that onInterceptTouchEvent() is a method from the ViewGroup class, and not from Activity.

You can achieve the desired behavior by moving your logic from onInterceptTouchEvent() to dispatchTouchEvent(MotionEvent ev). Remember to call the superclass implementation of dispatchTouchEvent(MotionEvent ev) to handle the events that should be handled normally.

Also note that you should consider a movement to be a swipe only when the delta is bigger than the system constant for touch slop. And I suggest making sure that the user is swiping in the direction you want by testing yDelta / 2 > xDelta instead of yDelta > xDelta.

public class Game extends Activity {
    private int mSlop;
    private float mDownX;
    private float mDownY;
    private boolean mSwiping;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.game_activity);

        ViewConfiguration vc = ViewConfiguration.get(this)
        mSlop = vc.getScaledTouchSlop();

       //other code....
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = ev.getX();
                mDownY = ev.getY();
                mSwiping = false;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if(mSwiping) {
                    swipeScreen(); //if action recognized as swipe then swipe
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = ev.getX();
                float y = ev.getY();
                float xDelta = Math.abs(x - mDownX);
                float yDelta = Math.abs(y - mDownY);

                if (yDelta > mSlop && yDelta / 2 > xDelta) {
                    mSwiping = true;
                    return true;
                }
                break;
        }

        return super.dispatchTouchEvent(ev);
    }
}
like image 190
brnunes Avatar answered Oct 08 '22 04:10

brnunes