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;
}});
}
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 onTouchEvent
s, 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.