0

Im trying to draw a square on a canvas but only the MotionEvent.ACTION_DOWN is run, and then the listener stops.

The idea is when the user touches the screen it get the x1 and y1 locations and every time the onTouch is fired it must draw the rect frim x1 y1 to the current location, and lastly save the last location in x2 y2 once the user lets go of the screen.

My code looks like this:

surfaceView.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        holder = surfaceView.getHolder();
        canvas = holder.lockCanvas();
        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            x1=event.getX();
            y1=event.getY();
        }
        else if(event.getAction() == MotionEvent.ACTION_UP)
        {
            x2=event.getX();
            y2=event.getY();
        }
        canvas.drawRect(x1, y1, event.getX(), event.getY(), paint);
        holder.unlockCanvasAndPost(canvas);
        return true;
    }
});

Can anyone give me an example.

string.Empty
  • 10,393
  • 4
  • 39
  • 67
  • is there a question here? – GreyBeardedGeek Feb 27 '13 at 06:11
  • Did you try to put a log on each event? – NaviRamyle Feb 27 '13 at 06:11
  • Yes only the MotionEvent.ACTION_DOWN is fired and then it stops. – string.Empty Feb 27 '13 at 06:14
  • add implements Callback to your class like this final class Surface extends SurfaceView implements Callback – ShreeshaDas Feb 27 '13 at 06:20
  • Need to check all code related to this listener, because part that you provided works fine in generic case. – SSemashko Feb 27 '13 at 06:20
  • What is `surfaceView` ? Is it the instance of `SurfaceView` ? – GrIsHu Feb 27 '13 at 06:52
  • @Grishu : Yes it is a `SurfaceView`. – string.Empty Feb 27 '13 at 07:12
  • Put this line inside your if condition as : `if(event.getAction() == MotionEvent.ACTION_DOWN) { x1=event.getX(); y1=event.getY(); canvas.drawRect(x1, y1, event.getX(), event.getY(), paint); }` – GrIsHu Feb 27 '13 at 07:43
  • i solved my issue a different way, i used 2 pointers to draw the square. `public boolean onTouch(View v, MotionEvent event) { if(event.getPointerCount()==2) { holder = surfaceView.getHolder(); canvas = holder.lockCanvas(); canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); x1=event.getX(0); y1=event.getY(0); x2=event.getX(1); y2=event.getY(1); canvas.drawRect(x1, y1, x2, y2, paint); holder.unlockCanvasAndPost(canvas); } return true; }` – string.Empty Feb 27 '13 at 08:14

2 Answers2

1

ACTION_UP triggers from above code. Try the code below and you will see the log.

I think your problem may be related with the points you get. I don't know how you defined x1, y1, x2, y2 but when declared out of scope they must be final. Try this instead.

final SurfaceView s = (SurfaceView) findViewById(R.id.surface);

final RectF rect = new RectF();

s.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        SurfaceHolder holder = s.getHolder();
        Canvas canvas = holder.lockCanvas();

        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.d("action", "down");
            rect.left = event.getX();
            rect.top = event.getY();
        }
        if(event.getAction() == MotionEvent.ACTION_UP){
            Log.d("action", "up");
            rect.right = event.getX();
            rect.bottom = event.getY();

            Paint paint = new Paint();
            paint.setColor(Color.RED);
            canvas.drawRect(rect, paint);
        }

        holder.unlockCanvasAndPost(canvas);
        return true;
    }
});
akaya
  • 1,140
  • 9
  • 27
  • The x1, y1, x2, y2 are not final but i got it to work without them being final. but good answer. – string.Empty Feb 27 '13 at 09:27
  • I have another problem now, even when i don't lift up it still sends a ACTION_CANCEL event. Do you know why this would happen? The log says: ACTION_DOWN ACTION_MOVE ACTION_MOVE ACTION_MOVE ACTION_CANCEL – string.Empty Feb 27 '13 at 11:33
  • You just need to google it. It is explained here. http://stackoverflow.com/questions/6018309/action-cancel-while-touching – akaya Feb 27 '13 at 11:38
  • Couldn't find it. Thanks though. – string.Empty Feb 27 '13 at 11:43
0

Try using this.

surfaceView.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {

        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            x1=event.getX();
            y1=event.getY();
        }
        else if(event.getAction() == MotionEvent.ACTION_UP)
        {
            x2=event.getX();
            y2=event.getY();

            holder = surfaceView.getHolder();
            canvas = holder.lockCanvas();
            canvas.drawRect(x1, y1, x2, y2, paint);
            holder.unlockCanvasAndPost(canvas);
        }

        return true;
    }
});

If you move your finger it calls the listener every move you do. So this code

holder = surfaceView.getHolder();
canvas = holder.lockCanvas();

and this code

canvas.drawRect(x1, y1, event.getX(), event.getY(), paint);
holder.unlockCanvasAndPost(canvas);

Will be executed, maybe that's why it's stopping.

So I put the drawRect inside the MotionEvent.ACTION_UP condition, so the drawRect will be executed once.

NaviRamyle
  • 3,967
  • 1
  • 31
  • 49