Oleksandr Firsov
Oleksandr Firsov

Reputation: 1478

Android Using OnTouchListener in Canvas

So, I'm developing an app where user will be able to interact with image, I need to use OnTouchListener, but I don't know how to do it properly. Whenever I click on image - nothing happens. In the end I'm trying to get circle that will appear when user touches the image and that'll move with the finger. Here's my MainActivity:

public class MainActivity extends Activity{



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");

        String fileString = file.getPath();


        takenPhoto = (ImageView) findViewById(R.id.imageView1);

        bmp = BitmapFactory.decodeFile(fileString);
        mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
        takenPhoto.setImageBitmap(mutableBitmap);

    }

    private static class DrawView extends View {



        public DrawView(Context context) {
            super(context);
        }


         public boolean onTouch(View view, MotionEvent event) {


                int action = event.getAction(); 

                drawPos.x = event.getX();
                drawPos.y = event.getY();

                switch (action) { 
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    drawing = true;
                    this.invalidate();
                    break; 
                case MotionEvent.ACTION_UP:   
                case MotionEvent.ACTION_CANCEL:
                    drawing = false;
                    this.invalidate();
                    break; 

                default: 
                    break; 
                }



             return true;
         }

         @Override
         protected void onDraw(Canvas canvas) {

             super.onDraw(canvas);

             if (drawing) {
                 canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
             }
         }





    }


}

Upvotes: 1

Views: 7215

Answers (2)

Simon Marquis
Simon Marquis

Reputation: 7516

A simpler solution would be to use a custom ImageView that will handle both the image and the draw:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

public class DrawingImageView extends ImageView {

    private PointF point;
    private Paint paint = new Paint();

    public DrawingImageView(Context context) {
        super(context);
    }

    public DrawingImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawingImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                point = new PointF(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                point.set(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                point = null;
                invalidate();
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        if (point != null) {
            canvas.drawCircle(point.x, point.y, 100, paint);
        }
    }
}

Then in your xml file:

    <your.package.DrawingImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

And in your Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //...
    view = (DrawingImageView) findViewById(R.id.image);
    //...
    view.setImageBitmap(mutableBitmap);
}

That's all

Upvotes: 3

Simon Marquis
Simon Marquis

Reputation: 7516

You need to remove the last onTouch method from your Activity and remove setOnTouchListener. Since the activity captures touch event, the view will never get access to it.

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");
        String fileString = file.getPath();
        takenPhoto = (ImageView) findViewById(R.id.imageView1);

        bmp = BitmapFactory.decodeFile(fileString);
        mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
        takenPhoto.setImageBitmap(mutableBitmap);
    }

    private static class DrawView extends View {

        public DrawView(Context context) {
            super(context);
        }

         public boolean onTouch(View view, MotionEvent event) {
                int action = event.getAction(); 
                drawPos.x = event.getX();
                drawPos.y = event.getY();

                switch (action) { 
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    drawing = true;
                    this.invalidate();
                    break; 
                case MotionEvent.ACTION_UP:   
                case MotionEvent.ACTION_CANCEL:
                    drawing = false;
                    this.invalidate();
                    break; 

                default: 
                    break; 
                }
             return true;
         }

         @Override
         protected void onDraw(Canvas canvas) {
             super.onDraw(canvas);
             if (drawing) {
                 canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
             }
         }
    }

}

Upvotes: 0

Related Questions