Home » Android » android – Method onTouchEvent not being called

android – Method onTouchEvent not being called

Posted by: admin April 23, 2020 Leave a comment

Questions:

I’m having a problem that my method

@Override
public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
}

is never called. Any ideas why is that so? I’m building a google’s API 4.0.3 application, and I’m trying to enable swipes for my ViewFliper. However, it can’t work because touch is never called.

Code:

 public class MainActivity extends SherlockMapActivity implements ActionBar.TabListener {

Thats the declaration of my activity. and to detect swipes i have implemented that:

    SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener(){

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {

        float sensitvity = 50;
        if((e1.getX() - e2.getX()) > sensitvity){
            SwipeLeft();
        }else if((e2.getX() - e1.getX()) > sensitvity){
            SwipeRight();
        }

        return true;
    }

};
GestureDetector gestureDetector= new GestureDetector(simpleOnGestureListener);

Thank You.

edit:

main.xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

<ViewFlipper
    android:id="@+id/ViewFlipper"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff" >

    <include
        android:layout_height="match_parent"
        layout="@layout/mymain" />

    <include layout="@layout/secondmain" />
    <include layout="@layout/thirdmain" />
    <include layout="@layout/fourthmain" />
</ViewFlipper>
</LinearLayout>

Edit2: all of my included layouts have scrollview implemented. Is it possible that scroll takes those events and handles them? And how to detect gestures if so?

How to&Answers:

I found a perfect solution. I implemented new method:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    View v = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

and now it all works fine!

Edit:

My final code:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    View v = getCurrentFocus();
    if (v instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];
        if (event.getAction() == MotionEvent.ACTION_UP
                && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w
                        .getBottom())) {

            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().getCurrentFocus()
                    .getWindowToken(), 0);
        }
    }
    boolean ret = super.dispatchTouchEvent(event);
    return ret;
}

Answer:

As I wrote in Gabrjan’s post’s comments that this fires continuously while touching the screen, there’s actually an easy way to get only the touch down events:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        System.out.println("TOUCH DOWN!");
        //set immersive mode here, or whatever...
    }
    return super.dispatchTouchEvent(event);
} 

This was very useful to me to put the Android into immersive mode whenever any part of the screen was touched regardless which element. But I didn’t wish to set immersive mode repeatedly!

Answer:

ok, now i’m sure that the problem is that scrollview handle touches, so anyway to ignore that and yet be the scrolling avaiable?

Yes that’s the problem, when android handles touch events each event goes from child to parent, so first it’s handled by ViewFlipper, but then it goes to ScrollView. So you have to implement getParent().requestDisallowInterceptTouchEvent(true) (see ViewParent class) in order to make all touch events handled by ViewFlipper, and then simply detect the direction of gesture if horizontal then flip view if not then pass touch event to ScrollView or just scroll ScrollView programmatically

EDIT: Also you can implement OnTouchListener in your ViewFlipper and in this listener trigger GestureDetector.onTouchEvent(event), but this also requires requestDisallowInterceptTouchEvent of your parent view set to true

Answer:

All gestures and touch events goes to the lowest element in view hierarchy who can handle it.
So if you have any listener in included layout you can call ((TypeOfParrent)yourView.getParent()).onTouchEvent(event) to delegate event to the handler you want.

ADD: I recoment you to use ViewPager for flipping views.
In the ViewPager you dont need to implements your own onGestureListener.

http://www.edumobile.org/android/android-beginner-tutorials/view-pager-example-in-android-development/

http://developer.android.com/reference/android/support/v4/view/ViewPager.html