Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a circle onto a view (android)

I am starting with my first attempts to write an android app. I'd like to to visualize the Monte-Carlo-Approximation for pi. Hence I first want to draw a Circle onto a view but i dont get it working! I have tried to create my own "CircleView" Class which extends "View" and overwrite the onDraw(..) method like its explained over here: How to draw circle by canvas in Android?

This is my CircleView Class

public class CircleView extends View {
    public CircleView(Context context) {
        super(context);
    }

    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(150);
        canvas.drawCircle(50,50,20,paint);
    }
}

I have inserted the CircleView into a LinearLayout with the following XML-code

<com.tak3r07.montecarlopi.CircleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/circleView"
    android:layout_weight="1"/>

(Btw Android Studio is telling me in the XML-view at the right side: "Rendering Problems Custom view CircleView is not using the 2- or 3-argument View constructors; XML attributes will not work")

The App just crashes with the following log: http://pastebin.com/Gv1GaHtX

Can someone tell what i did wrong?

I thought this setup would create an activity with a view which displays a circle.

Regards

Edit: Crash is fixed by adding the 2 and 3 Parameter Constructor in CircleView (See https://stackoverflow.com/a/13797457/3248708)

But now i still do not see any Circle in the activity

like image 610
Tak3r07 Avatar asked Sep 21 '14 16:09

Tak3r07


1 Answers

A couple of observations:

You need to take into account the width and height assigned to your view when determining your circle's center point and radius.

You should take into account the padding assigned to your View so you don't draw in that reserved portion.

You should avoid allocating objects within your onDraw method since this gets called a lot.

In order to allow your view to be specified in an XML layout, you need to provide the constructor that takes a Context and an AttributeSet. The AttributeSet is the mechanism by which your XML attributes are passed to your view.

Give this a try:

package com.tak3r07.montecarlopi;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View
{
    private static final int DEFAULT_CIRCLE_COLOR = Color.RED;

    private int circleColor = DEFAULT_CIRCLE_COLOR;
    private Paint paint;

    public CircleView(Context context) 
    {
        super(context);
        init(context, null);
    }

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

    private void init(Context context, AttributeSet attrs)
    {
        paint = new Paint();
        paint.setAntiAlias(true);
    }

    public void setCircleColor(int circleColor)
    {
        this.circleColor = circleColor;
        invalidate();
    }

    public int getCircleColor()
    {
        return circleColor;
    }

    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        int w = getWidth();
        int h = getHeight();

        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();

        int usableWidth = w - (pl + pr);
        int usableHeight = h - (pt + pb);

        int radius = Math.min(usableWidth, usableHeight) / 2;
        int cx = pl + (usableWidth / 2);
        int cy = pt + (usableHeight / 2);

        paint.setColor(circleColor);
        canvas.drawCircle(cx, cy, radius, paint);
    }
}
like image 145
Michael Krause Avatar answered Oct 08 '22 17:10

Michael Krause