37

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?

Jitesh Prajapati
  • 2,533
  • 4
  • 29
  • 51
gabrjan
  • 3,080
  • 9
  • 40
  • 69
  • ok, now i'm sure that the problem is that scrollview handle touches, so anyway to ignore that and yet be the scrolling avaiable? – gabrjan Oct 26 '12 at 09:13

4 Answers4

55

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;
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
gabrjan
  • 3,080
  • 9
  • 40
  • 69
  • Thanks, this is a much easier solution than the one by @Chaosit. – Johannes Rudolph May 25 '13 at 16:21
  • Hi - where did you implement this new method? And what does it return? – Jona Jun 25 '14 at 10:45
  • Check edited answer. I have that function implemented in my MainActivity.java file. Or better to say in main class of app. – gabrjan Jun 26 '14 at 06:56
  • I was using onTouchEvent with my webview and it seemed that as my WV got more complex the onTouchEvent method became less and less stable. dispatchTouchEvent works nicely to guarantee that touches are detected but will eat cpu as it fires continuously while holding (and i dont think onTouchEvent fires continuously). – Logic1 Jun 14 '15 at 10:58
  • Is `dispatchTouchEvent` official method of **ViewPager**? – IgorGanapolsky Nov 03 '22 at 12:53
15

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!

Logic1
  • 1,806
  • 3
  • 26
  • 43
6

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

Chaosit
  • 1,116
  • 7
  • 21
3

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

Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67