Sunday, 6 January 2013

How to create custom progress bar and progress dialog in Android.

Advertisement


Progress Bar and Progress Dialog are useful to tell user that the task is takes longer time to finish. A Progress Dialog showing a progress indicator and an optional text message or view. Only a text message or a view can be used at the same time.
In this tutorial, we show you how to display a custom progress bar and use progress dialog in Asynctask to tell user that the file download task is running.

Here is a result of this tutorial:

Android Custom ProgressBar And ProgressDialog Example


This project is developed in Eclipse 4.2.0.

1. Make main layout with some components: one button to show custom progress bars, one textview to show some infos, one button to start download image file from internet Url.


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">
        <Button
            android:id="@+id/button1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dp"
            android:text="Show Progressbar" 
            android:onClick="button_click"
                android:layout_margin="5dip"
            />
       
        <ProgressBar
            android:id="@+id/progressBar1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            style="@style/CustomProgressBar" 
            android:layout_margin="5dip"/>
       
        <ProgressBar
            android:id="@+id/progressBar2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
                    android:indeterminateDrawable="@drawable/my_progress_indeterminate"
            android:layout_margin="5dip"/>
        <TextView
             android:id="@+id/textView"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:gravity="center"
             android:text="show state up checkbox"
             android:layout_margin="5dip"
             android:textColor="#CC00CC"
             android:textSize="18dp"/>
       
        <Button
             android:id="@+id/button2"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="20dp"
             android:text="Start download file" 
                android:onClick="button_click"
                android:layout_margin="5dip"
            />
       
        <!-- Image view to show image after downloading -->
    <ImageView android:id="@+id/my_image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
To customize progress bars on xml file above and a progress style of progress dialog when downloading file, we will edit style property of each progress bar.
For progress bar with horizoltal style:
            style="@style/CustomProgressBar" 
Define CustomProgressBar style in res/values/styles.xml:
<resources> 
        <style name="CustomProgressBar"parent="android:Widget.ProgressBar.Horizontal">
          <item name="android:indeterminateOnly">false</item>
          <item name="android:progressDrawable">@drawable/custom_progress_bar_horizontal</item>
          <item name="android:minHeight">10dip</item>
          <item name="android:maxHeight">20dip</item>
        </style>       
    <style name="AppTheme"parent="android:Theme.Light" />
</resources>
And in file res/drawable/custom_progress_bar_horizontal.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--  @author : @alexduhem
                blog.sakaroz.com
 -->
<layer-list
        xmlns:android="http://schemas.android.com/apk/res/android">
        <item
                android:id="@android:id/background">
                <shape>
                        <corners
                                android:radius="5dip" />
                        <gradient
                                android:startColor="#ffffffff"
                                android:centerColor="#ffdddddd"
                                android:centerY="0.50"
                                android:endColor="#ffffffff"
                                android:angle="270" />
                </shape>
        </item>
        <item
                android:id="@android:id/secondaryProgress">
                <clip>
                        <shape>
                                <corners
                                        android:radius="5dip" />
                                <gradient
                                        android:startColor="#770e75af"
                                        android:endColor="#771997e1"
                                        android:angle="90" />
                        </shape>
                </clip>
        </item>
        <item
                android:id="@android:id/progress">
                <clip>
                        <shape>
                                <corners
                                        android:radius="5dip" />
                                <gradient
                                        android:startColor="#ff0e75af"
                                        android:endColor="#ff1997e1"
                                        android:angle="90" />
                        </shape>
                </clip>
        </item>
</layer-list>

For progress bar with spinner style:
                    android:indeterminateDrawable="@drawable/my_progress_indeterminate"

Content of res/drawable/my_progress_indeterminate.xml:
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/loadingicon"
    android:pivotX="50%"
        android:pivotY="50%"/>

2. Code
2.1. Starting a new asynctask to show custom two progress bars working when click on button. One horizontal style and one spinner style.
 Create asyncTask class: ShowCustomProgressBarAsyncTask
  public class ShowCustomProgressBarAsyncTask extends AsyncTask<Void, Integer, Void> {
  int myProgress;
  @Override
  protected void onPostExecute(Void result) {
   textview.setText("Finish work with custom ProgressBar");
   button1.setEnabled(true);
   progressBar2.setVisibility(View.INVISIBLE);
  }
  @Override
  protected void onPreExecute() {
   button1.setEnabled(false);
   textview.setText("Start work with custom ProgressBar");
   myProgress = 0;
   progressBar.setSecondaryProgress(0);
  }
  @Override
  protected Void doInBackground(Void... params) {
   while(myProgress<100){
    myProgress++;
    publishProgress(myProgress);
       SystemClock.sleep(100);
   }
   return null;
  }
  @Override
  protected void onProgressUpdate(Integer... values) {
   progressBar.setProgress(values[0]);
   progressBar.setSecondaryProgress(values[0] + 5);
  }
 }
2.2. When User clicks on the download file button, processing download and show custom progress dialog by starting a new asynctask.
In doInBackground method we process for download data from Url, then write to file located in SDCard.
After downloading image from the web then reading the downloaded image from the sdcard and displaying in a imageview, do this in onPostExecute method. All codes to work below:

/* Background Async Task to download file */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
                /*  Before starting background thread. Show Progress Bar Dialog */
                @SuppressWarnings("deprecation")
                @Override
                protected void onPreExecute() {
                        super.onPreExecute();
                        showDialog(CUSTOM_PROGRESS_DIALOG);
                }
                /* Downloading file in background thread */
                @Override
                protected String doInBackground(String... f_url) {
                        int count;
                try {
                    URL url = new URL(f_url[0]);
                    URLConnection conection = url.openConnection();
                    conection.connect();
                    // getting file length
                    int lenghtOfFile = conection.getContentLength();
                    // input stream to read file - with 8k buffer
                    InputStream input = newBufferedInputStream(url.openStream(), 8192);
                    // Output stream to write file
                    OutputStream output = new FileOutputStream("/sdcard/filedownload.jpg");
                    byte data[] = new byte[1024]; 
                    long total = 0;
                    while ((count = input.read(data)) != -1) {
                        total += count;
                        // publishing the progress....
                        // After this onProgressUpdate will be called
                        publishProgress(""+(int)((total*100)/lenghtOfFile));
                        // writing data to file
                        output.write(data, 0, count);
                    }
                    // flushing output
                    output.flush();
                    // closing streams
                    output.close();
                    input.close();
                   
                } catch (Exception e) {
                        Log.e("Error: ", e.getMessage());
                }
                return null;
                }
                /* Updating progress bar */
                protected void onProgressUpdate(String... value) {
                        // setting progress percentage
                        pDialog.setProgress(Integer.parseInt(value[0]));
                        pDialog.setSecondaryProgress(Integer.parseInt(value[0]) + 5);
     }
                /*  After completing background task. Dismiss the progress dialog */
                @SuppressWarnings("deprecation")
                @Override
                protected void onPostExecute(String file_url) {
                        // dismiss the dialog after the file was downloaded
                        dismissDialog(CUSTOM_PROGRESS_DIALOG);
                        // Displaying downloaded image into image view
                        // Reading image path from sdcard
                        String imagePath = Environment.getExternalStorageDirectory().toString() + "/filedownload.jpg";
                        // setting downloaded into image view
                        my_image.setImageDrawable(Drawable.createFromPath(imagePath));
                }
        }

Note: add some permission in androidmanifest.xml file to work with Internet and External Storage SDCard:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />

3.DEMO
3.1. Run application

Android Custom ProgressBar And ProgressDialog Example
  
3.1. Click on first button

Android Custom ProgressBar And ProgressDialog Example

3.2. Click on Download file button

Android Custom ProgressBar And ProgressDialog Example

Android Custom ProgressBar And ProgressDialog Example


You can download all source codes of this tutorial from here.
Reference: http://www.androidhive.info


EmoticonEmoticon