10

How do i make the bitmap created clickable? Below is the code which i have used to create a bitmap using canvas.

 public class DrawView extends View implements OnClickListener
{
    public DrawView(Context context)
    {
        super(context);
        paint = new Paint();
        image = BitmapFactory.decodeResource(getResources(), R.drawable.andmrktsmall);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        int canWidth = canvas.getWidth();
        int canHeight = canvas.getHeight();
        int width = (canWidth - 200) / 2;
        int height = (canHeight - 100) / 2;
        Bitmap indexcanvas = Bitmap.createScaledBitmap(image, 200, 100, true);
        canvas.drawBitmap(indexcanvas, width, height, paint);
        this.setBackgroundColor(Color.YELLOW);

    }

    @Override
    public void onClick(View v)
    {
        Toast.makeText(context, "View is clicked", 1).show();
    }

}
learner
  • 3,092
  • 2
  • 21
  • 33
Prashanth
  • 156
  • 1
  • 4
  • 14
  • Do you mean like HTML MAP? --> http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_areamap – Daniel Sep 16 '13 at 11:31
  • http://stackoverflow.com/questions/10710579/make-clickable-region-in-canvas-to-change-image or http://stackoverflow.com/questions/16451656/make-a-javascript-canvas-rectangle-clickable – Daniel Sep 16 '13 at 11:34
  • No.normal click event on the bitmap created.Basically the bitmap/view made should be clickable. – Prashanth Sep 16 '13 at 11:39

2 Answers2

25

By setting an OnClickListener on this view, all of it will be clickable (though not limited to your bitmap). To check whether or not the user clicked only the bitmap itself you have to override onTouchEvent(MotionEvent event) and check if the touch coordinates are the same as the bitmap.

@Override
public boolean onTouchEvent(MotionEvent event)
{
    float x = event.getX();
    float y = event.getY();
    switch(event.getAction())
    {
        case MotionEvent.ACTION_DOWN:
        //Check if the x and y position of the touch is inside the bitmap
        if( x > bitmapXPosition && x < bitmapXPosition + bitmapWidth && y > bitmapYPosition && y < bitmapYPosition + bitmapHeight )
        {
            //Bitmap touched
        }
        return true;
    }
    return false;
}

Just replace bitmapXPosition and bitmapYPosition with the coordinates you use to draw the bitmap, and bitmapWidth and bitmapHeight with the width and height you use to draw it.

Also, try not to allocate memory (create objects) inside the onDraw() method of any view. It is bad for perfomance.

EDIT

private Rect r;
private Paint paint;
Bitmap bitmap;

public TestRect(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    paint = new Paint();
    paint.setColor(Color.BLUE);
    r = new Rect();
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
}

public TestRect(Context context, AttributeSet attrs) {
    super(context, attrs);
    paint = new Paint();
    paint.setColor(Color.BLUE);
    r = new Rect();
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
}

public TestRect(Context context) {
    super(context);
    paint = new Paint();
    paint.setColor(Color.BLUE);
    r = new Rect();
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
}

@Override
public void onDraw(Canvas c)
{

    r.set(getWidth()/2, getHeight()/2, getWidth()/2 + 200, getHeight()/2 + 200);
    //c.drawRect(r, paint);
    c.drawBitmap(bitmap, null, r, paint);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
    float x = event.getX();
    float y = event.getY();
    switch(event.getAction())
    {
        case MotionEvent.ACTION_DOWN:
        //Check if the x and y position of the touch is inside the bitmap
        if( x > getWidth()/2 && x < getWidth()/2 + 200 && y > getHeight()/2 && y < getHeight()/2 + 200 )
        {
            Log.e("TOUCHED", "X: " + x + " Y: " + y);
            //Bitmap touched
        }
        return true;
    }
    return false;
}

By drawing the bitmap using a Rect as your coordinates you can check if the touch is inside the bitmap or not. Also, instead of that big and ugly "if" statement, you can use

if(r.contains(x, y))
{
     //BITMAP TOUCHED
}
LuigiPower
  • 1,113
  • 10
  • 20
  • Not working.On touch event itself is not called on touching the image. – Prashanth Sep 16 '13 at 11:49
  • It should be called each time you touch the View. I'll check to be sure, but this is what I used in certain projects. – LuigiPower Sep 16 '13 at 11:53
  • Just tried it in a sample project, it works. If you want I'll edit my post to add the sample code. – LuigiPower Sep 16 '13 at 12:01
  • It works i was missing super method.But i am not able to get the calculation right for the touch event on the image.It would be heplful if you could post your sample code. – Prashanth Sep 16 '13 at 12:24
  • @LuigiPower how to identify individual bitmap touches?when we have multiple bitmaps on the canvas? – onexf Apr 17 '18 at 06:48
  • Create multiple rectangles, one for each bitmap, then test then contains on each one. – LuigiPower Apr 24 '18 at 14:31
6
@Override
 public boolean onTouchEvent(MotionEvent event) 
 {
    int x=(int)event.getX();
    int y=(int)event.getY();
    if (drawable.getBounds().contains(x,y)  &&
           event.getAction()==MotionEvent.ACTION_DOWN)
        {
            Log.e(TAG, "onTouchEvent: drawable touched ");
            return true;
        }
        return false;
    }
adhi
  • 326
  • 4
  • 6