Custom progress bar in android application gives it a personal touch. In this tutorial, we’ll create a custom progress bar by implementing a spinning logo icon in our application. Most of the time, we end up using a ProgressBar as the loading icon while the data gets loaded. Going by the current trend, apps like Reddit, UBER, Foodpanda and Twitter have replaced the commonly used Progress Bar with their application’s icon as the loading icon. This gives their application as well as logo brand a touch that makes them stand out from the rest.
Let’s see the classical way of showing a loading icon in our application’s activity. The code for the layout above should look like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.journaldev.spinninglogo.MainActivity">
<ProgressBar
android:id="@+id/progressBarLarge"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/progressBarSmall"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBarLarge" />
<ProgressBar
android:id="@+id/progressBarMedium"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/progressBarLarge"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
We’ve set three circular ProgressBars that rotate endlessly in the above layout. Now let’s try to add a ProgressBar that spins an icon indeterminately.
The ProgressBar class contains an attribute indeterminateDrawable
which replaces the default indicator with the drawable specified. Let’s see what happens when we place an icon in the ProgressBar. The code for activity_main.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.journaldev.spinninglogo.MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
The output that the above layout reflects in our application is given below. Oops! What’s wrong with the ProgressBar? Why isn’t it rotating? Well we need to set a RotateDrawable as the value of the attribute. A RotateDrawable
is defined in the xml by encapsulating the current drawable and assigning it the angle and degrees of rotation. The tag <rotate> is used to do so in the xml as shown below. The code for the progress_icon.xml
RotateDrawable is given below.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="https://schemas.android.com/apk/res/android" >
<item>
<rotate
android:drawable="@mipmap/ic_launcher"
android:fillAfter="true"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
</item>
</layer-list>
The attribute android:fillAfter
indicates that the transformation is applied after the animation is over. android:toDegrees
value can be increased or decreased to change the speed of rotation. Generally it’s recommended to set it in multiples of 360. Let’s set the above drawable in the ProgressBar present in the activity_main.xml.
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/progress_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
The output reflected in the application is shown below. Let’s create a basic application that displays a string in a TextView from an ArrayList after a delay. The code for the xml layout file activity_main.xml
is given below.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.journaldev.spinninglogo.MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/progress_icon"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="TAP ME TO GET A RANDOM QUOTE"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A Greeting Message Awaits You"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Take note of the efficient use of ConstraintLayout in the above code. The code for the MainActivity.java is given below.
package com.journaldev.spinninglogo;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
TextView textView;
List<String> quotesList;
ProgressBar progressBar;
int i = 0;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
quotesList = new ArrayList<>();
quotesList.add("Hi");
quotesList.add("Happy New Year");
quotesList.add("Hope you have a good day");
quotesList.add("Merry Christmas");
Button btnTap = findViewById(R.id.button);
textView = findViewById(R.id.textView);
progressBar = findViewById(R.id.progressBar);
btnTap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressBar.setVisibility(View.VISIBLE);
textView.setVisibility(View.GONE);
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (i == quotesList.size())
i = 0;
textView.setVisibility(View.VISIBLE);
textView.setText(quotesList.get(i++));
progressBar.setVisibility(View.GONE);
}
}, 3000);
}
});
}
}
The output of the above application in action is given below. Note: Ignore the flickering rotation in the gifs. It’s absolutely smooth when running on a device. This brings an end to this tutorial. We’ve implemented a RotationDrawable inside a ProgressBar to achieve a spinning logo like indicator. This should be good for showing a loading progress in apps. You can download the final Android Custom Progress Bar project from the link below.
Download Android Custom Progress Bar Project
Reference: API Doc
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
I am not proper understand your program code…Please explain it brefily…If it is possible for you!
- Gurpreet Singh