Drawing Circle programmatically using Android ShapeDrawable

21,794

Solution 1

Give same height and width to your TextView

<TextView
            android:id="@+id/txt_count"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:textColor="@color/text_grey"
            android:gravity="center"
            android:textSize="12sp"
            android:padding="2dp"
            />

Solution 2

This is too late to answer but hope it will help someone else. If want to draw circle like this, dont bother with 46.0% as it is only text view.

enter image description here.

public class Circle extends View {

private Paint mCircleYellow;
private Paint mCircleGray;

private float mRadius;
private RectF mArcBounds = new RectF();

public Circle(Context context) {
    super(context);

    // create the Paint and set its color

}

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

    initPaints();
}

public Circle(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

private void initPaints() {
    mCircleYellow = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCircleYellow.setStyle(Paint.Style.FILL);
    mCircleYellow.setColor(Color.YELLOW);
    mCircleYellow.setStyle(Paint.Style.STROKE);
    mCircleYellow.setStrokeWidth(15 * getResources().getDisplayMetrics().density);
    mCircleYellow.setStrokeCap(Paint.Cap.SQUARE);
    // mEyeAndMouthPaint.setColor(getResources().getColor(R.color.colorAccent));
    mCircleYellow.setColor(Color.parseColor("#F9A61A"));

    mCircleGray = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCircleGray.setStyle(Paint.Style.FILL);
    mCircleGray.setColor(Color.GRAY);
    mCircleGray.setStyle(Paint.Style.STROKE);
    mCircleGray.setStrokeWidth(15 * getResources().getDisplayMetrics().density);
    mCircleGray.setStrokeCap(Paint.Cap.SQUARE);
    // mEyeAndMouthPaint.setColor(getResources().getColor(R.color.colorAccent));
    mCircleGray.setColor(Color.parseColor("#76787a"));

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    mRadius = Math.min(w, h) / 2f;

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int w = MeasureSpec.getSize(widthMeasureSpec);
    int h = MeasureSpec.getSize(heightMeasureSpec);

    int size = Math.min(w, h);
    setMeasuredDimension(size, size);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Float drawUpto = 46f;


    float mouthInset = mRadius / 3f;
    mArcBounds.set(mouthInset, mouthInset, mRadius * 2 - mouthInset, mRadius * 2 - mouthInset);
    canvas.drawArc(mArcBounds, 0f, 360f, false, mCircleGray);

    canvas.drawArc(mArcBounds, 270f, drawUpto, false, mCircleYellow);


}

}

So use this class in your xml file as it is a view class.

Share:
21,794
Chandru
Author by

Chandru

I am an elegant and enthusiastic developer who always believes the myth of working smart rather working hard.

Updated on June 12, 2020

Comments

  • Chandru
    Chandru almost 4 years

    I have a requirement in my project to draw a circle in runtime dynamically. So for that purpose I am using ShapeDrawable to create circle programmatically, but unfortunately I could not find any class or methods inside ShapeDrawable for CircleShape, instead I found only OvalShape(). So kindly please help me to draw a circle through ShapeDrawable by just passing diameter or radius of the circle. Thanks in advance. Any kind of customization would be useful for me to fix my solution.

    Code I am using for ShapeDrawable is

    public static ShapeDrawable drawCircle (Context context, int width, int height, int color) {
    
            //////Drawing oval & Circle programmatically /////////////
    
            ShapeDrawable oval = new ShapeDrawable (new OvalShape ());
            oval.setIntrinsicHeight (height);
            oval.setIntrinsicWidth (width);
            oval.getPaint ().setColor (color);
            return oval;
        }
    

    Code using in MainActivity.java

    if(Build.VERSION.SDK_INT >= 16) {
                txtCount.setBackground (Util.drawCircle (MainActivity.this, 50, 50, getResources ().getColor (R.color.yellow)));
                txtHotelCount.setText ("20");
            }else{
                txtCount.setBackgroundDrawable (Util.drawCircle (MainActivity.this, 50, 50, getResources ().getColor (R.color.yellow)));
                txtHotelCount.setText ("20");
    
            }
    

    xml using for TextView txtCount in my project for is

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:background="@color/white">
    
            <TextView
                android:id="@+id/txt_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/text_grey"
                android:gravity="center"
                android:textSize="12sp"
                android:padding="2dp"
                />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/text_grey"
                android:text="AVAILABLE"
                android:layout_marginLeft="10dp"
                android:gravity="center"
                />
        </LinearLayout>
    

    But still no luck even after setting the same width and height as 50. The property is behaving still like oval.