-
Notifications
You must be signed in to change notification settings - Fork 0
Handling ProgressBars
ProgressBar is used to display the progress of an activity while the user is waiting. You can display an indeterminate progress (spinning wheel) or result-based progress.
We can display an indeterminate progress bar which we show to indicate waiting:
<ProgressBar
android:id="@+id/pbLoading"
android:visibility="invisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
and then manage the visibility in the activity:
// on some click or some loading we need to wait for...
ProgressBar pb = (ProgressBar) findViewById(R.id.pbLoading);
pb.setVisibility(ProgressBar.VISIBLE);
// run a background job and once complete
pb.setVisibility(ProgressBar.INVISIBLE);
Typically you want to try to put the ProgressBar
in the place where data is going to show (i.e. as a placeholder for an image). For a ListView, you put the ProgressBar in the header or footer, which lets you put an arbitrary layout outside of the adapter.
ProgressBar can be used to report the progress of a long-running AsyncTask. In this case:
- ProgressBar can report numerical results for a task.
- Must specify horizontal style and result max value.
- Must
publishProgress(value)
in your AsyncTask
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
style="?android:attr/progressBarStyleHorizontal"
android:max="100" />
and then within the AsyncTask:
public class DelayTask extends AsyncTask<Void, Integer, String> {
int count = 0;
@Override
protected void onPreExecute() {
pb.setVisibility(ProgressBar.VISIBLE);
}
@Override
protected String doInBackground(Void... params) {
while (count < 5) {
SystemClock.sleep(1000);
count++;
publishProgress(count * 20);
}
return "Complete";
}
@Override
protected void onProgressUpdate(Integer... values) {
pb.setProgress(values[0]);
}
}
and using this pattern any background tasks can be reflected by an on-screen progress report.
We can add a ProgressBar
into our ActionBar
or Toolbar
using a custom ActionView. First, let's define the progress action-view with a layout file in res/layout/action_view_progress.xml
with a progress-bar:
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pbProgressAction" />
Next, we can add the ActionView
to our ActionBar
in the res/menu/activity_main.xml
as an item
:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item
android:id="@+id/miActionProgress"
android:title="Loading..."
android:visible="false"
android:orderInCategory="100"
app:showAsAction="always"
app:actionLayout="@layout/action_view_progress" />
</menu>
Note the use of android:orderInCategory
to append the item at the end (other items should be less than 100), android:visible
which hides the menu item and also app:actionLayout
which specifies the layout for the action-view. Next, we can use the onPrepareOptionsMenu
method to get a reference to the menu item and the associated view within the activity:
public class MainActivity extends AppCompatActivity {
// Instance of the progress action-view
MenuItem miActionProgressItem;
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Store instance of the menu item containing progress
miActionProgressItem = menu.findItem(R.id.miActionProgress);
// Extract the action-view from the menu item
ProgressBar v = (ProgressBar) MenuItemCompat.getActionView(miActionProgressItem);
// Return to finish
return super.onPrepareOptionsMenu(menu);
}
}
Finally, we can toggle the visibility of the miActionProgressItem
item to show and hide the progress-bar in the action-bar:
public class MainActivity extends AppCompatActivity {
public void showProgressBar() {
// Show progress item
miActionProgressItem.setVisible(true);
}
public void hideProgressBar() {
// Hide progress item
miActionProgressItem.setVisible(false);
}
}
and the result:
Often the user is waiting for a list of items to be populated into a ListView
. In these cases, we can display the progress bar at the bottom of the ListView
using a footer. First, let's define the footer xml layout in res/layout/footer_progress.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pbFooterLoading"
android:layout_gravity="center_horizontal"
android:visibility="gone" />
</LinearLayout>
Note the use of a LinearLayout
with the layout_height
set to wrap_content
as this is important for the footer to be properly hidden. Next, let's setup the footer within our ListView
by inflating and inserting the header within the activity:
public class MainActivity extends AppCompatActivity {
// ...
// Store reference to the progress bar later
ProgressBar progressBarFooter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
setupListWithFooter();
}
// Adds footer to the list default hidden progress
public void setupListWithFooter() {
// Find the ListView
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Inflate the footer
View footer = getLayoutInflater().inflate(
R.layout.footer_progress, null);
// Find the progressbar within footer
progressBarFooter = (ProgressBar)
footer.findViewById(R.id.pbFooterLoading);
// Add footer to ListView before setting adapter
lvItems.addFooterView(footer);
// Set the adapter AFTER adding footer
lvItems.setAdapter(myAdapter);
}
}
Now with the progressBarFooter
progress-bar instance stored we can show and hide the footer with setVisibility
:
public class MainActivity extends AppCompatActivity {
// Show progress
public void showProgressBar() {
progressBarFooter.setVisibility(View.VISIBLE);
}
// Hide progress
public void hideProgressBar() {
progressBarFooter.setVisibility(View.GONE);
}
}
Now we can call these show and hide methods as needed to show the footer in the list:
In certain scenarios, a simple solution for displaying a progress bar during a long-running operation is to display a modal progress dialog indicating a task is running:
[[|Using-DialogFragment#displaying-a-progressdialog]]
Note that this modal display prevents the user from interacting with the app until the task is completed. As a result, the progress indicators above generally provide a better user experience.
See this list of third-party progress bars for alternate styles and animations.
The NumberProgressBar is featured above for example.
Created by CodePath with much help from the community. Contributed content licensed under cc-wiki with attribution required. You are free to remix and reuse, as long as you attribute and use a similar license.
Finding these guides helpful?
We need help from the broader community to improve these guides, add new topics and keep the topics up-to-date. See our contribution guidelines here and our topic issues list for great ways to help out.
Check these same guides through our standalone viewer for a better browsing experience and an improved search. Follow us on twitter @codepath for access to more useful Android development resources.
Interested in ramping up on Android quickly?
(US Only) If you are an existing engineer with 2+ years of professional experience in software development and are serious about ramping up on Android quickly, be sure to apply for our free evening 8-week Android bootcamp.
We've trained over a thousand engineers from top companies including Apple, Twitter, Airbnb, Uber, and many others leveraging this program. The course is taught by Android experts from the industry and is specifically designed for existing engineers.
Not in the United States? Please fill out our application of interest form and we’ll notify you as classes become available in your area powered by local organizers.