Search code examples
androidviewandroid-viewandroid-custom-view

Custom view measuring


I have made a custom view - it extends View. In the onDraw() method I create a circle with a set radius. At the moment in my xml, I have the layout_width and layout_height set to wrap_content. The circle is the right size, but when I set an onClickListener I don't have to touch the circle for it to register. I can tap anywhere where there is no other view.

I think I need to do something with onMeasure or LayoutParams but I don't know what exactly.

The aim is for the onClickListener to only be called when I click the circle with the layout_width and height still being set to wrap_content.

EDIT:

This creates a square not a circle as I wanted.

Here is my code:

protected void onDraw(Canvas canvas) {

        canvas.drawCircle(canvas.getWidth() /2 , canvas.getHeight() /2,
                RADIUS, paint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        widthMeasureSpec = RADIUS;
        heightMeasureSpec = RADIUS;

        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);

    }

Solution

  • Try this:

    float mTranslateX;
    float mTranslateY;
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.save();
        canvas.translate(mTranslateX, mTranslateY);
        canvas.drawCircle(0, 0, RADIUS, paint);
        canvas.restore();
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int dia = RADIUS * 2;
        int w = resolveSize(dia, widthMeasureSpec);
        int h = resolveSize(dia, heightMeasureSpec);
        setMeasuredDimension(w, h);
        float radius = Math.min(w, h)/2F;
        mTranslateX = radius;
        mTranslateY = radius;
    }