Reputation: 3891
I am trying to use the onScroll method in my custom View. onDown and onLongPress work, but why doesn't my onScroll or onFling or onDoubleTap work? Here's my code, it's almost everything as Google provided it in their developer.android.com website...
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.*;
public class GameView extends View implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener{
public static int cols = 10;
public static int rows = 9;
private String DEBUG_TAG = "Debug";
private GestureDetectorCompat mDetector;
private GameThread mGameThread;
private Sprite mSprite;
private MineField mMineField;
private Context context;
private Paint mPaint;
public GameView(Context context) {
super(context);
this.context = context;
if(mMineField == null)buildMineField(cols, rows);
mPaint = new Paint();
mSprite = new Sprite(context, this);
mGameThread = new GameThread(this, mSprite, mMineField);
mGameThread.start();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.FILL);
mPaint.setTextSize(50);
mDetector = new GestureDetectorCompat(context, this);
}
public Sprite getSprite() {
return mSprite;
}
public MineField getMineField() {
return mMineField;
}
public void buildMineField(int cols, int rows) {
if(cols >= 1 && rows >= 1) {
mMineField = new MineField(cols, rows, context, this);
}
}
public void drawMineField(Canvas canvas) {
for(int i = 0; i < mMineField.rows; i++) {
for(int j = 0; j < mMineField.cols; j++) {
canvas.drawBitmap(mMineField.mines[j][i].getBitmap(), mMineField.mines[j][i].getX(), mMineField.mines[j][i].getY(), null);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
drawMineField(canvas);
if(mSprite.isVisible()) {
canvas.drawBitmap(mSprite.getBitmap(), mSprite.getX(), mSprite.getY(), null);
}
canvas.drawText(Long.toString(mGameThread.getFPS()), 50, 50, mPaint);
}
@Override
public void postInvalidate() {
super.postInvalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
@Override
public boolean onDoubleTap(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.d(DEBUG_TAG, "onDoubleTap: " + e.toString());
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDown(MotionEvent arg0) {
Log.d(DEBUG_TAG,"onDown: " + arg0.toString());
return true;
}
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onLongPress(MotionEvent arg0) {
Log.d(DEBUG_TAG, "onLongPress: " + arg0.toString());
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
Log.d(DEBUG_TAG, "onScroll");
return true;
}
@Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
}
I just updated the code and the onDown() method was edited to "return false"
@Override
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
// Be sure to call the superclass implementation
return super.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG,"onDown: " + event.toString());
return false;
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
return true;
}
@Override
public void onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
return true;
}
@Override
public void onShowPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
return true;
}
@Override
public boolean onDoubleTap(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
return true;
}
But nevertheless, when touching the screen I get a "OnDown" debug notification as well as an "OnShowPress" and "OnLongPress"... But I've set the return to false?
Upvotes: 1
Views: 7000
Reputation: 503
Of course... So your problem is "simple"
@Override
public boolean onDown(MotionEvent arg0) {
Log.d(DEBUG_TAG,"onDown: " + arg0.toString());
return false;
}
If you return false... You will tell the listener: "I did not consume this event" and let it "bubble"
Upvotes: 2
Reputation: 1420
I had some similar problem, developing something like this in xamarin (using c# instead of java) for android.
I solved it returning false in the events like onDown(...), BUT returning true in the onTouchEvent(), so try something like this to check if works:
@Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return true;
}
By the way, you are implementing OnGestureListener, so I think that perhaps the methods like onDown() should not been overriden. The onTouchEven() however needs to be overriden.
// without the overriden directive
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG,"onDown: " + event.toString());
return false;
}
Hope this helps you to find the solution.
Upvotes: 7
Reputation: 31
Returning true
inside onTouchEvent
works for me too.
But it doesn't feel right, as it will intercept all "clicks", even if you don't intend to.
I firstly resolved this issue through a test like :
if (event.getAction()==MotionEvent.ACTION_SCROLL)
inside the onTouchEvent
, but it doesn't work all the time.
I assume my comprehension is not good enough.
Upvotes: 0