96

I am trying to achieve this progress bar design: enter image description here

The current code that I have produces this: enter image description here

This is the code:

<item android:id="@android:id/background">
    <shape>
        <corners android:radius="8dp"/>
        <solid android:color="@color/dirtyWhite"/>
    </shape>
</item>

<item android:id="@android:id/progress">
    <clip>
        <shape>
            <corners android:radius="8dp"/>
            <solid android:color="@color/colorPrimaryDark"/>
        </shape>
    </clip>
</item>

My progress bar:

 <ProgressBar
            android:id="@+id/activeProgress"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:progress="10"
            android:progressDrawable="@drawable/rounded_corners_progress_bar"/>

I tried adding <size> attribute on the <shape> in <clip to make the progress shape a bit smaller but it did not work. Also, the progress bar is flat and I want to be curved as per design. What I need to change in order to achieve the design?

Georgi Koemdzhiev
  • 9,882
  • 11
  • 51
  • 101

5 Answers5

180

How to make the progress shape a bit smaller?

You need to give the progress item a little padding, like so:

<item android:id="@android:id/progress"
    android:top="2dp"
    android:bottom="2dp"
    android:left="2dp"
    android:right="2dp">

How to make the progress bar to be curved as per design?

Replace the <clip></clip> element, with <scale android:scaleWidth="100%"></scale>. That will make the shape keep its form as it grows - and not cut off. Unfortunately, it will have a little unwanted visual effect at the beginning - as the shape corners don't have enough space to draw. But it might be good enough for most cases.

Full code:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:id="@android:id/background">
    <shape>
        <corners android:radius="8dp"/>
        <solid android:color="@color/dirtyWhite"/>
    </shape>
 </item>

 <item android:id="@android:id/progress"
    android:top="1dp"
    android:bottom="1dp"
    android:left="1dp"
    android:right="1dp">

    <scale android:scaleWidth="100%">
        <shape>
            <corners android:radius="8dp"/>
            <solid android:color="@color/colorPrimaryDark"/>
        </shape>
    </scale>
 </item>
</layer-list>
Chathura Wijesinghe
  • 3,052
  • 2
  • 20
  • 41
Eyal Biran
  • 5,188
  • 1
  • 26
  • 29
  • Thank you for your answer. However, when I applied your suggestions. the whole progress bar got coloured with my main color (colorPrimaryDark) although the progress attribute as set to 10% No idea why this happened. I edited my answer with the progress bar code as well. – Georgi Koemdzhiev Mar 07 '17 at 11:22
  • Thanks! It achieves the progress bar curve effect. However, when I apply your suggestions the whole progress bar gets filled up as it it is set to 100% progress. Do you know what is causing this? Thanks! – Georgi Koemdzhiev Mar 07 '17 at 11:27
  • Worked! Thank you so much for your time! :) – Georgi Koemdzhiev Mar 07 '17 at 11:36
  • Please its does not work properly with gradient progress, when we set 100 % width , it round both ends of progress but it also wrapup the gradient, but i want show graidient according to progress value. if you have any solution pleas share – habib ullah Nov 07 '17 at 13:30
  • How can we remove the unwanted visual effect - flat progress at the beginning when the progress is very small ?? @EyalBiran – Akshay Mahajan Nov 08 '17 at 03:33
  • 4
    @habibullah Using the native ProgressBar and Layer-List is very restricting. You can easily implement a custom progress bar to fit your needs. For example, if you have a solid color background - simply use a foreground 9-path to hide everything but the progress. If you are targeting newer Android Versions you can simply use the built in mask support (not supported in older versions). Another option is to use a library, this might be good for you: https://github.com/akexorcist/Android-RoundCornerProgressBar . If you are still having problems, please post a new question. Cheers. – Eyal Biran Nov 08 '17 at 13:10
  • 1
    @AkshayMahajan see comment above – Eyal Biran Nov 08 '17 at 13:10
  • 1
    When I applied your full code, the whole progress bar got coloured with my main color (colorPrimaryDark) although the progressis not 100%. I added clip tag under @android:id/background, it fixed, but background has gone. My temp solution is removing background item and adding background color to layout (without rounded corners). – Oğuzhan Koşar Feb 14 '18 at 11:40
  • @EyalBiran hello, thank your for the answer, its working, but i didn't see the progress when i try to execute the progress bar from 100 to 0, i ever try adding one more item with id secondaryProgress, but it doesn't work, did you have any solution? please share, thank you – MNFS Apr 18 '18 at 09:50
  • 8
    In my case, the `scale` with `android:scaleWidth="100%"` did the trick in order to display it with rounded corners. Many thanks – Edison Spencer Apr 25 '18 at 21:27
  • `scale` instead of `clip` mainly does the trick. Then rest is your customization whether you want the rounded corners on both sides or only a single side. :) Thanks @EyalBiran for the answer. – Abhishek Aug 31 '18 at 10:08
  • 1
    Thanks. You saved my day. – Nguyễn Anh Tuấn Jan 13 '20 at 16:26
20

With the Material Components Library you can use the LinearProgressIndicator and the app:trackCornerRadius attribute.
Something like:

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

enter image description here

It works also for the determinate progress indicator removing the android:indeterminate="true" or using android:indeterminate="false"

Note: it requires at least the version 1.3.0.

Gabriele Mariotti
  • 192,671
  • 57
  • 469
  • 489
  • 2
    @Arunachalamk LinearProgressIndicator [was introduced](https://github.com/material-components/material-components-android/blob/1.3.0-alpha04/lib/java/com/google/android/material/progressindicator/LinearProgressIndicator.java) with the **1.3.0-alpha04**, currently the latest alpha version. – Gabriele Mariotti Dec 03 '20 at 19:41
  • I was trying to achieve the same effect on a circular progress view and this helped me. trackCornerRadius exists for that as well. Docs on both linear and circular progress indicators available here https://github.com/material-components/material-components-android/blob/master/docs/components/ProgressIndicator.md – speedynomads Feb 24 '21 at 19:02
  • Can we add rounded border to LinearProgressIndicator when indeterminate="false"? – nilesh May 24 '21 at 08:45
  • @nilesh Currently there isn't a parameter to add a stroke. – Gabriele Mariotti May 24 '21 at 09:45
  • @GabrieleMariotti Ok, thanks for help. – nilesh May 24 '21 at 09:52
10

Thanks to Georgi Koemdzhiev for a nice question and images. For those who want to make similar to his, do the following.

1) Create a background for a ProgressBar.

progress_bar_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <corners android:radius="3dp" />
    <stroke android:color="@color/white" android:width="1dp" />
</shape>

2) Create a scale for the ProgressBar.

curved_progress_bar.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="2dp" />
            <solid android:color="@color/transparent" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="2dp" />
                <solid android:color="#ffff00" />
            </shape>
        </clip>
    </item>
</layer-list>

3) In layout file add the ProgressBar.

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="6dp"
    android:layout_marginStart="20dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="20dp"
    android:background="@drawable/progress_bar_background"
    >

    <ProgressBar
        android:id="@+id/progress_bar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="4dp"
        android:layout_margin="1dp"
        android:indeterminate="false"
        android:progressDrawable="@drawable/curved_progress_bar"
        />

</FrameLayout>
CoolMind
  • 16,738
  • 10
  • 131
  • 165
4

The code produce following progress bar
You can achieve progress bar with both inner progress color ,border color,empty progress with transparent color.

<?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="15dip" />
        <stroke android:width="1dp" android:color="@color/black" />
    </shape>
</item>

<item android:id="@android:id/secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="@color/black"
                android:centerColor="@color/trans"
                android:centerY="0.75"
                android:endColor="@color/black"
                android:angle="270"

                />
        </shape>
    </clip>
 </item>


 <item
    android:id="@android:id/progress"
    >
    <clip>
        <shape>
            <corners
                android:radius="5dip" />
            <gradient
                android:startColor="@color/black"
                android:endColor="@color/black"
                android:angle="270" />
        </shape>
    </clip>
 </item>
 </layer-list>
  • Hi Ravichandra, thanks for your answer! Can you add explanation why your code answers his question? Otherwise, it'll be difficult to use for other users. Thanks! – Nander Speerstra Jun 27 '19 at 11:48
  • Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. Furthermore, try to explain why your answer is better than the other answers already given to this question. – Qw3ry Jun 27 '19 at 11:49
0
<com.google.android.material.progressindicator.LinearProgressIndicator
                android:id="@+id/pb_team2"
                android:layout_width="0dp"
                android:layout_height="8dp"
                android:layout_marginStart="55dp"
                android:layout_marginEnd="15dp"
                app:trackColor="#E0E0E0"
                app:trackCornerRadius="6dp"
                app:trackThickness="8dp"
                android:progress="2"
                app:indicatorColor="@color/red"
                android:scaleX="-1"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@id/tv_versus"
                app:layout_constraintTop_toBottomOf="@id/tv_team2_score" />
Gv Ravi
  • 25
  • 3