Question

I have been staring at this all night now. I am trying to make a simple interactive ball game for Android, but I just can't seem to get the onFling method working. My logs that are in onFling don't appear in LogCat, and there is no response to a fling gesture. I think I'm doing something wrong with the gesturedetector or gesturelistener. Please help me out so I can finally go to sleep :) . This is my code:

This is outside of onCreate, but still in the Activity:

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

SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener() {

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        ballSpeed.x = velocityX;
        ballSpeed.y = velocityY;
        Log.d("TAG", "----> velocityX: " + velocityX);
        Log.d("TAG", "----> velocityY: " + velocityY);

        return true;

    }
};

GestureDetector gestureDetector = new GestureDetector(null,
        simpleOnGestureListener);

EDIT:

Apparently the above code does work. That means that the mistake is somewhere else. @bobnoble says that I should post my onCreate() method:

@Override
public void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE); // hide title bar
    getWindow().setFlags(0xFFFFFFFF,LayoutParams.FLAG_FULLSCREEN| LayoutParams.FLAG_KEEP_SCREEN_ON);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // create pointer to main screen
    final FrameLayout mainView = (android.widget.FrameLayout) findViewById(R.id.main_view);

    // get screen dimensions
    Display display = getWindowManager().getDefaultDisplay();

    try {
        display.getSize(size);
        screenWidth = size.x;
        screenHeight = size.y;
    } catch (NoSuchMethodError e) {
        screenWidth = display.getWidth();
        screenHeight = display.getHeight();
    }

    ballPosition = new android.graphics.PointF();
    ballSpeed = new android.graphics.PointF();

    // create variables for ball position and speed
    ballPosition.x = 4 * screenWidth / 5;
    ballPosition.y = 2 * screenHeight / 3;
    ballSpeed.x = 0;
    ballSpeed.y = 0;

    // create initial ball
    ballView = new BallView(this, ballPosition.x, ballPosition.y, 20);

    mainView.addView(ballView); // add ball to main screen
    ballView.invalidate(); // call onDraw in BallView

    //listener for touch event 
    mainView.setOnTouchListener(new android.view.View.OnTouchListener() {
        public boolean onTouch(android.view.View v, android.view.MotionEvent e) {
            //set ball position based on screen touch
            ballPosition.x = e.getX();
            ballPosition.y = e.getY();
            ballSpeed.y = 0;
            ballSpeed.x = 0;
            //timer event will redraw ball
            return true;
        }}); 

}
Was it helpful?

Solution

I put the code you provided into an Activity, commenting out the ballSpeed lines and added Log output. Works as expected. The logcat showing the output is at the end.

If this does not work for you, the issue is somewhere else in your Activity code. You may want to post your onCreate method.

@Override
public boolean onTouchEvent(MotionEvent me) {
    Log.i(TAG, "onTouchEvent occurred...");
    return gestureDetector.onTouchEvent(me);
}

SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener() {

    @Override
    public boolean onDown(MotionEvent e) {
        Log.i(TAG, "onDown event occurred...");
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//          ballSpeed.x = velocityX;
//          ballSpeed.y = velocityY;
        Log.d("TAG", "----> velocityX: " + velocityX);
        Log.d("TAG", "----> velocityY: " + velocityY);

        return true;
    }
};

GestureDetector gestureDetector = new GestureDetector(null,
        simpleOnGestureListener);

Logcat shows multiple onTouchEvents, the onDown and the onFling

11-18 15:51:25.364: I/SO_MainActivity(13415): onTouchEvent occurred...
11-18 15:51:25.364: I/SO_MainActivity(13415): onDown event occurred...
...
11-18 15:51:25.584: I/SO_MainActivity(13415): onTouchEvent occurred...
11-18 15:51:25.604: I/SO_MainActivity(13415): onTouchEvent occurred...
11-18 15:51:25.664: D/TAG(13415): ----> velocityX: 3198.8127
11-18 15:51:25.664: D/TAG(13415): ----> velocityY: -1447.966

Edit based on looking at the onCreate method:

The mainView.setOnTouchListener onTouch method is consuming the touches by returning true. By returning true, the onTouch method is indicating it has completely handled the touch event, and not to propagate it further.

Change it to return false; will cause it to propagate the touch event and you should see the other touch event methods getting called.

OTHER TIPS

Do you have `implements OnGestureListener' on your Activity declaration?

See this snippet

http://www.androidsnippets.com/gesturedetector-and-gesturedetectorongesturelistener

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top