Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android round edges on ring shaped progressbar

I'm trying to make a circular progress bar on android and it seems pretty straightforward task , but I'm struggling with rounding the edges of the progress and secondary progress.

Is there a way to do that without making a custom view ? Using a corners radius ? or nine patch drawable ?

For this view (see attachement) I'm using a simple xml file

<item android:id="@android:id/progress">       <shape         android:useLevel="true"         android:innerRadius="@dimen/sixty_dp"         android:shape="ring"         android:thickness="@dimen/seven_dp">          <solid android:color="#477C5B"/>          <stroke android:width="1dip"             android:color="#FFFF"/>     </shape>       </item> 

enter image description here

like image 976
moujib Avatar asked Jul 04 '15 10:07

moujib


People also ask

How do I make a custom circular progress bar?

This example demonstrates how do I make circle custom progress bar in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.

What is android App rounded?

Android 12 introduces Rounded Corner API that enables you to get the properties of a screen's rounded corners, such as its center and its radius. As you can see in the image above, with this API you app can be made aware of the screen's rounded corner and avoid truncating the UI elements.

What is stroke in shape android?

Sometimes you want an outline around your shape and to do that you can use the stroke tag. You can specify the width and color of the outline using android:width and android:color.


1 Answers

Just create class called MyProgress in your package .. and paste the following code..

import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.text.TextPaint; import android.util.AttributeSet; import android.view.View;  public class MyProgress extends View {      private Paint mPrimaryPaint;     private Paint mSecondaryPaint;     private RectF mRectF;     private TextPaint mTextPaint;     private Paint mBackgroundPaint;      private boolean mDrawText = false;      private int mSecondaryProgressColor;     private int mPrimaryProgressColor;     private int mBackgroundColor;      private int mStrokeWidth;      private int mProgress;     private int mSecodaryProgress;      private int mTextColor;      private int mPrimaryCapSize;     private int mSecondaryCapSize;     private boolean mIsPrimaryCapVisible;     private boolean mIsSecondaryCapVisible;      private int x;     private int y;     private int mWidth = 0, mHeight = 0;       public MyProgress(Context context) {         super(context);         init(context, null);     }      public MyProgress(Context context, AttributeSet attrs) {         super(context, attrs);         init(context, attrs);     }      public MyProgress(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);         init(context, attrs);     }      void init(Context context, AttributeSet attrs) {         TypedArray a;         if (attrs != null) {             a = context.getTheme().obtainStyledAttributes(                     attrs,                     R.styleable.MyProgress,                     0, 0);         } else {             throw new IllegalArgumentException("Must have to pass the attributes");         }          try {             mDrawText = a.getBoolean(R.styleable.MyProgress_showProgressText, false);              mBackgroundColor = a.getColor(R.styleable.MyProgress_backgroundColor, android.R.color.darker_gray);             mPrimaryProgressColor = a.getColor(R.styleable.MyProgress_progressColor, android.R.color.darker_gray);             mSecondaryProgressColor = a.getColor(R.styleable.MyProgress_secondaryProgressColor, android.R.color.black);              mProgress = a.getInt(R.styleable.MyProgress_progress, 0);             mSecodaryProgress = a.getInt(R.styleable.MyProgress_secondaryProgress, 0);              mStrokeWidth = a.getDimensionPixelSize(R.styleable.MyProgress_strokeWidth, 20);             mTextColor = a.getColor(R.styleable.MyProgress_textColor, android.R.color.black);              mPrimaryCapSize = a.getInt(R.styleable.MyProgress_primaryCapSize, 20);             mSecondaryCapSize = a.getInt(R.styleable.MyProgress_secodaryCapSize, 20);              mIsPrimaryCapVisible = a.getBoolean(R.styleable.MyProgress_primaryCapVisibility, true);             mIsSecondaryCapVisible = a.getBoolean(R.styleable.MyProgress_secodaryCapVisibility, true);         } finally {             a.recycle();         }          mBackgroundPaint = new Paint();         mBackgroundPaint.setAntiAlias(true);         mBackgroundPaint.setStyle(Paint.Style.STROKE);         mBackgroundPaint.setStrokeWidth(mStrokeWidth);         mBackgroundPaint.setColor(mBackgroundColor);          mPrimaryPaint = new Paint();         mPrimaryPaint.setAntiAlias(true);         mPrimaryPaint.setStyle(Paint.Style.STROKE);         mPrimaryPaint.setStrokeWidth(mStrokeWidth);         mPrimaryPaint.setColor(mPrimaryProgressColor);          mSecondaryPaint = new Paint();         mSecondaryPaint.setAntiAlias(true);         mSecondaryPaint.setStyle(Paint.Style.STROKE);         mSecondaryPaint.setStrokeWidth(mStrokeWidth - 2);         mSecondaryPaint.setColor(mSecondaryProgressColor);          mTextPaint = new TextPaint();         mTextPaint.setColor(mTextColor);          mRectF = new RectF();     }      @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         mRectF.set(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());         mTextPaint.setTextSize(w / 5);         x = (w / 2) - ((int) (mTextPaint.measureText(mProgress + "%") / 2));         y = (int) ((h / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2));         mWidth = w;         mHeight = h;         invalidate();     }      @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);          mPrimaryPaint.setStyle(Paint.Style.STROKE);         mSecondaryPaint.setStyle(Paint.Style.STROKE);          // for drawing a full progress .. The background circle         canvas.drawArc(mRectF, 0, 360, false, mBackgroundPaint);          // for drawing a secondary progress circle         int secondarySwipeangle = (mSecodaryProgress * 360) / 100;         canvas.drawArc(mRectF, 270, secondarySwipeangle, false, mSecondaryPaint);          // for drawing a main progress circle         int primarySwipeangle = (mProgress * 360) / 100;         canvas.drawArc(mRectF, 270, primarySwipeangle, false, mPrimaryPaint);          // for cap of secondary progress         int r = (getHeight() - getPaddingLeft() * 2) / 2;      // Calculated from canvas width         double trad = (secondarySwipeangle - 90) * (Math.PI / 180d); // = 5.1051         int x = (int) (r * Math.cos(trad));         int y = (int) (r * Math.sin(trad));         mSecondaryPaint.setStyle(Paint.Style.FILL);         if (mIsSecondaryCapVisible)             canvas.drawCircle(x + (mWidth / 2), y + (mHeight / 2), mSecondaryCapSize, mSecondaryPaint);          // for cap of primary progress         trad = (primarySwipeangle - 90) * (Math.PI / 180d); // = 5.1051         x = (int) (r * Math.cos(trad));         y = (int) (r * Math.sin(trad));         mPrimaryPaint.setStyle(Paint.Style.FILL);         if (mIsPrimaryCapVisible)             canvas.drawCircle(x + (mWidth / 2), y + (mHeight / 2), mPrimaryCapSize, mPrimaryPaint);           if (mDrawText)             canvas.drawText(mProgress + "%", x, y, mTextPaint);     }      public void setDrawText(boolean mDrawText) {         this.mDrawText = mDrawText;         invalidate();     }      public void setBackgroundColor(int mBackgroundColor) {         this.mBackgroundColor = mBackgroundColor;         invalidate();     }      public void setSecondaryProgressColor(int mSecondaryProgressColor) {         this.mSecondaryProgressColor = mSecondaryProgressColor;         invalidate();     }      public void setPrimaryProgressColor(int mPrimaryProgressColor) {         this.mPrimaryProgressColor = mPrimaryProgressColor;         invalidate();     }      public void setStrokeWidth(int mStrokeWidth) {         this.mStrokeWidth = mStrokeWidth;         invalidate();     }      public void setProgress(int mProgress) {         this.mProgress = mProgress;         invalidate();     }      public void setSecondaryProgress(int mSecondaryProgress) {         this.mSecodaryProgress = mSecondaryProgress;         invalidate();     }      public void setTextColor(int mTextColor) {         this.mTextColor = mTextColor;         invalidate();     }      public void setPrimaryCapSize(int mPrimaryCapSize) {         this.mPrimaryCapSize = mPrimaryCapSize;         invalidate();     }      public void setSecondaryCapSize(int mSecondaryCapSize) {         this.mSecondaryCapSize = mSecondaryCapSize;         invalidate();     }      public boolean isPrimaryCapVisible() {         return mIsPrimaryCapVisible;     }      public void setIsPrimaryCapVisible(boolean mIsPrimaryCapVisible) {         this.mIsPrimaryCapVisible = mIsPrimaryCapVisible;     }      public boolean isSecondaryCapVisible() {         return mIsSecondaryCapVisible;     }      public void setIsSecondaryCapVisible(boolean mIsSecondaryCapVisible) {         this.mIsSecondaryCapVisible = mIsSecondaryCapVisible;     }       public int getSecondaryProgressColor() {         return mSecondaryProgressColor;     }      public int getPrimaryProgressColor() {         return mPrimaryProgressColor;     }      public int getProgress() {         return mProgress;     }      public int getBackgroundColor() {         return mBackgroundColor;     }      public int getSecodaryProgress() {         return mSecodaryProgress;     }      public int getPrimaryCapSize() {         return mPrimaryCapSize;     }      public int getSecondaryCapSize() {         return mSecondaryCapSize;     } } 

and add the following line in res->values->attr.xml under a tag and build it

<declare-styleable name="MyProgress">     <attr name="showProgressText" format="boolean" />     <attr name="progress" format="integer" />     <attr name="secondaryProgress" format="integer" />     <attr name="progressColor" format="color" />     <attr name="secondaryProgressColor" format="color" />     <attr name="backgroundColor" format="color" />     <attr name="primaryCapSize" format="integer" />     <attr name="secodaryCapSize" format="integer" />     <attr name="primaryCapVisibility" format="boolean" />     <attr name="secodaryCapVisibility" format="boolean" />     <attr name="strokeWidth" format="dimension" />     <attr name="textColor" format="color" /> </declare-styleable> 

that's it .... and to use in your layout ..

<Your_Package_Name.MyProgress     android:padding="20dp"     android:id="@+id/timer1"     app:strokeWidth="10dp"     app:progress="30"     app:secondaryProgress="50"     app:backgroundColor="@android:color/black"     app:progressColor="@android:color/holo_blue_bright"     app:secondaryProgressColor="@android:color/holo_blue_dark"     app:primaryCapSize="30"     app:secodaryCapSize="40"     app:primaryCapVisibility="true"     app:secodaryCapVisibility="true"     android:layout_width="200dp"     android:layout_height="200dp" /> 

You can also change all property progrmatically using setMethods()... enter image description here

feel free to ask anything .. best of luck

[Update 23-01-2016]

finally I uploaded code on github. You can refer it from here https://github.com/msquare097/MProgressBar

Now You can use this ProgressBar by simply writing following line in your app build.gradle file. You don't have to copy above code.

compile 'com.msquare.widget.mprogressbar:mprogressbar:1.0.0' 
like image 196
Moinkhan Avatar answered Oct 07 '22 00:10

Moinkhan