I'm trying to create a custom progress bar in an app we're working on, and the last piece I need is the progress indicator itself. Instead, I want to have that bar be rounded just like the left- and right-hand edges of the progress bar itself, like in the second image (minus the red circle of course).
Here's the layout definition of the progress bar (the rest of the layout file omitted for brevity):
<ProgressBar android:id="@+id/progress_bar" android:layout_width="fill_parent" android:layout_height="60dp" android:padding="3dp" android:max="100" android:progressDrawable="@drawable/progress_bar_states" android:layout_marginTop="10dp" style="?android:attr/progressBarStyleHorizontal" android:indeterminateOnly="false" android:layout_below="@id/textview2" android:layout_alignLeft="@id/textview2" />
and here's the progress_bar_states.xml file:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="#20ffff00"/> <corners android:radius="60dp"/> </shape> </item> <item android:id="@android:id/progress"> <clip> <shape> <solid android:color="#20ffffff"/> <corners android:radius="60dp"/> </shape> </clip> </item> </layer-list>
How do I do this? I don't see any options to allow me to define the progress indicator at all. Should I be doing this a different way? I'm still pretty new at Android, so any guidance is appreciated.
@Ando - your solution is very close to what I need. The start of the indicator movement is the issue now, and I'm guessing it's because it's not a clip like the original. When the indicator starts, and up to a certain point in the beginning, it looks like it is "squeezed"
until it gets to the appropriate point then it looks fine:
How do we accomplish the 'clipping' at the start with this solution?
For @bladefury - as you can see, compared to the leading edge of the image above, it does appear to be flattened.
EDIT : After not looking at this for quite some time, I looked at a new component at https://github.com/akexorcist/Android-RoundCornerProgressBar/issues, and it has the same issue as the suggestions here.
CircularProgressIndicator , 4dp indicator/track thickness is used without animation for visibility change. Without customization, primaryColor will be used as the indicator color; the track is transparent.
just Change your progress_bar_states.xml file: like below example
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@android:id/background"> <shape> <solid android:color="#20ffff00" /> <corners android:radius="20dp" /> </shape> </item> <item android:id="@android:id/progress"> <!-- <clip> --> <!-- <shape> --> <!-- <solid android:color="@android:color/black" /> --> <!-- <corners --> <!-- android:bottomRightRadius="30dp" --> <!-- android:radius="60dp" --> <!-- android:topRightRadius="30dp" /> --> <!-- </shape> --> <!-- </clip> --> <scale android:drawable="@drawable/custom_progress_primary" android:scaleWidth="98%" /><!-- change here --> </item>
here custom_progress_primary.xml file: like below
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp" /> <solid android:color="@android:color/white" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape>
An option that's perhaps a bit more practical is implementing a custom Progress Bar view.
public class CustomProgressBar extends View { // % value of the progressbar. int progressBarValue = 0; public CustomProgressBar(Context context) { super(context); } public CustomProgressBar(Context context, AttributeSet attrs) { super(context, attrs); progressBarValue = attrs.getAttributeIntValue(null, "progressBarValue", 0); } public void setValue(int value) { progressBarValue = value; invalidate(); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); float cornerRadius = 30.0f; // Draw the background of the bar. Paint backgroundPaint = new Paint(); backgroundPaint.setColor(Color.LTGRAY); backgroundPaint.setStyle(Paint.Style.FILL); backgroundPaint.setAntiAlias(true); RectF backgroundRect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight()); canvas.drawRoundRect(backgroundRect, cornerRadius, cornerRadius, backgroundPaint); // Draw the progress bar. Paint barPaint = new Paint(); barPaint.setColor(Color.GREEN); barPaint.setStyle(Paint.Style.FILL); barPaint.setAntiAlias(true); float progress = (backgroundRect.width() / 100) * progressBarValue; RectF barRect = new RectF(0, 0, progress, canvas.getClipBounds().bottom); canvas.drawRoundRect(barRect, cornerRadius, cornerRadius, barPaint); // Draw progress text in the middle. Paint textPaint = new Paint(); textPaint.setColor(Color.WHITE); textPaint.setTextSize(34); String text = progressBarValue + "%"; Rect textBounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), textBounds); canvas.drawText(text, backgroundRect.centerX() - (textBounds.width() / 2), backgroundRect.centerY() + (textBounds.height() / 2), textPaint); } }
Then in your layout:
<view.CustomProgressBar android:layout_height="30dp" android:layout_width="match_parent" progressBarValue="66"/>
Which yields the result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With