Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create ImageView that is round, so click will work on round area only android

Hi I am creating tabla App,

For example

enter image description here

It should not respond outside of round but ImageView is Rectangle so it is responding

I am sure you can understand this problem

ImageView is rectangle but it's image is round, but I want to detect click only on round image...

like image 956
Siddhpura Amit Avatar asked Jan 22 '15 13:01

Siddhpura Amit


3 Answers

Thank you for your all support, based on your support I have done by below way and it is working perfect

ImageView imgView = (ImageView) findViewById(R.id.imageView1);
        imgView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                //CIRCLE :      (x-a)^2 + (y-b)^2 = r^2 
                float centerX, centerY, touchX, touchY, radius;
                centerX = v.getWidth() / 2;
                centerY = v.getHeight() / 2;
                touchX = event.getX();
                touchY = event.getY();
                radius = centerX;
                System.out.println("centerX = "+centerX+", centerY = "+centerY);
                System.out.println("touchX = "+touchX+", touchY = "+touchY);
                System.out.println("radius = "+radius);
                if (Math.pow(touchX - centerX, 2)
                        + Math.pow(touchY - centerY, 2) < Math.pow(radius, 2)) {
                    System.out.println("Inside Circle");
                    return false;
                } else {
                    System.out.println("Outside Circle");
                    return true;
                }
            }
        });
like image 150
Siddhpura Amit Avatar answered Nov 18 '22 11:11

Siddhpura Amit


It would seem that you will have to calculate whether or not the user is touching within the circular view. This will have to be achieved by overriding the touch event of the custom ImageView class that I assume you have already written.

Originally I had thought that drawing a circular area would have been enough, but that is not the case.

Pseudocode:

public class CustomImageView implements ImageView
{
    private Point centerPoint;
    private float radius;

    @Override
    protected void onDraw(Canvas canvasF) 
    {
        Drawable drawable = getDrawable();
        if(centerPoint == null)
        {
            centerPoint = new Point (getWidth() / 2, getHeight() / 2);
            /* 
             * if radius extends to edges, but if circular code 
             * exists already then we should already know what the 
             * radius is at this point I would assume.
             */
            radius = getWidth() / 2;
        }

        /*
         * remaining draw code for manipulating a circle.
         */
    }

    private boolean isInsideCircle(Point touchedPoint)
    {
         int distance = (int) Math.round(Math.pow(touchedPoint.x - centerPoint.x, 2) + Math.pow(touchedPoint.y - centerPoint.y, 2));

         if(distance < Math.pow(radius, 2))
         {
             return true;
         }
         else
         {
             return false;
         }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        Point touchedPoint = new Point(Math.round(event.getX()),   Math.round(event.getY()));

        if(isInsideCircle(touchedPoint))
        {
            return super.onTouchEvent(event);
        }

        return true;
    }
}

I might now end up adding this to my ImageView class to expand upon it and provide touch events only within the image when I need them as well.

If the image goes all the way to the edges then the radius is a little easier to determine. Otherwise, there will need to be a little extra done to figure out what the radius of the actual area is.

like image 41
Jay Snayder Avatar answered Nov 18 '22 09:11

Jay Snayder


You can attach the View.OnTouchListener to your ImageView. In that listener has only one method called OnTouchListener#onTouch (View v, MotionEvent event). The event argument has methods which allow to get the touch coordinates.
When you obtain the touch coordinates, relative to the ImageView size, you can check if the following inequality is true: (x - x0) ^ 2 + (y - y0) ^ 2 <= R ^ 2, where (x,y) - ImageView center coordinates, (x0, y0) - touch coordinates, R is the ImageView drawable radius (in your case it will be the half of ImageView width).
If it's true you can propagate the touch event further and return false, otherwise return true.

like image 2
aga Avatar answered Nov 18 '22 11:11

aga