Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progress bar rounded on both sides in android

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.

like image 639
youri Avatar asked Jan 16 '10 20:01

youri


4 Answers

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:

<ProgressBar
    android:id="@+id/custom_progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:indeterminateOnly="false"
    android:progressDrawable="@drawable/custom_progress_bar_horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="13"
    android:progress="33"
    android:secondaryProgress="66" />

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:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background"
          android:drawable="@android:drawable/custom_progress_bg" />
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_secondary" />
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_primary" />
    </item>
</layer-list>

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:

<item android:id="@android:id/background">
    <shape>
        <corners android:radius="6.5dp" />

        <solid android:color="@android:color/white" />

        <stroke
            android:width="1dp"
            android:color="@android:color/darker_gray" />
    </shape>
</item>

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: Primary progress bar
Example secondary xdpi png with padding before the tool: Secondary progress bar

And the final output: Custom progress bar

like image 62
Funktional Avatar answered Nov 20 '22 12:11

Funktional


Just change the label <clip> to <scale> like this:

<scale android:scaleWidth="100%">
like image 39
codingbubble Avatar answered Nov 20 '22 14:11

codingbubble


As far as I know, this is not possible. Because internally ClipDrawable (i.e. clip tag) cuts the given shape/drawable using canvas.clipRect(). Btw, you can copy the ClipDrawable source from here and clip a particular path based on the progress level.

like image 3
Karan Avatar answered Nov 20 '22 12:11

Karan


You can use the LinearProgressIndicator provided by the Material Components Library and the app:trackCornerRadius attribute.

Something like:

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:indeterminate="true"
        app:indicatorSize="xxdp"
        app:trackCornerRadius="xdp"/>

enter image description here

Note: it requires at least the version 1.3.0-alpha04.

like image 2
Gabriele Mariotti Avatar answered Nov 20 '22 13:11

Gabriele Mariotti