I am trying to create a custom progress bar in android. I have used the following xml file for it (progress_bar_horizontal.xml):
<?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>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FFFF"/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FF00"/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FF00"/>
</shape>
</clip>
</item>
</layer-list>
Everything works great apart from the fact I would like to have the progress in my progress bar rounded on both sides. The aforementioned code makes a progress bar to be rounded on the left hand side and simply cut (not rounded) on the right hand side. It is because of the clip tag probably. Could you please help me on that? What should i change to have the progress in my progress bar rounded on both sides?
The full layout goes below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/gradient_progress"
android:padding="10dip"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/progress_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="Uploading"
/>
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="55%"
android:paddingLeft="10dip"
/>
</LinearLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/progress_bar_horizontal"
android:maxHeight="12dip"
android:minHeight="12dip"
android:max="100"
/>
</LinearLayout>
</LinearLayout>
Here is the result of my effort: link text
I would like the red bar to have rounded edges on the right hand side as well. Thank you so much for your comments.
Final rounded both sides progress bar without 9-patch is:
android:progressDrawable="@drawable/progress_horizontal_green"
As far as I know, this is not possible. Because internally
ClipDrawable
(i.e. clip tag) cuts the given shape/drawable usingcanvas.clipRect()
. Btw, you can copy theClipDrawable
source from here and clip a particular path based on the progress level.Here's an updated answer for the times:
The Android source code uses Patch 9 files to achieve the effect: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/res/res/drawable/progress_horizontal_holo_dark.xml/
So start in your layout xml:
You can move a lot of this to a style xml but that's beside the point. What we really care about is
android:progressDrawable="@drawable/custom_progress_bar_horizontal"
- which is going to allow us to specify our own custom progress bars:Or you don't have to use a Patch 9 for your background- for example here's a simple white background with a 1dp border:
Android Asset Studio has an awesome tool to help you generate Patch 9 files: http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html
Example primary xdpi png with padding before the tool:
Example secondary xdpi png with padding before the tool:
And the final output:
Just change the label
<clip>
to<scale>
like this:In order to solve the problem where the end graphics overlap themselves when the progress is very low, I've written an extension to the ProgressBar class that adds a fixed start offset to the progress bar, while otherwise functioning as normal.
Just call 'setMaxWithPercentOffset()' or 'setMaxWithOffset()' rather than 'setMax()' passing in the value you want to add as a start offset to the progress bar.
If anyone has solved this problem without requiring the start offset let me know!