Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import com.android.internal.R;
     20 
     21 import android.content.Context;
     22 import android.content.res.TypedArray;
     23 import android.graphics.drawable.Drawable;
     24 import android.os.Bundle;
     25 import android.os.Handler;
     26 import android.os.Message;
     27 import android.text.Spannable;
     28 import android.text.SpannableString;
     29 import android.text.style.StyleSpan;
     30 import android.view.LayoutInflater;
     31 import android.view.View;
     32 import android.widget.ProgressBar;
     33 import android.widget.TextView;
     34 
     35 import java.text.NumberFormat;
     36 
     37 /**
     38  * <p>A dialog showing a progress indicator and an optional text message or view.
     39  * Only a text message or a view can be used at the same time.</p>
     40  * <p>The dialog can be made cancelable on back key press.</p>
     41  * <p>The progress range is 0..10000.</p>
     42  */
     43 public class ProgressDialog extends AlertDialog {
     44 
     45     /** Creates a ProgressDialog with a circular, spinning progress
     46      * bar. This is the default.
     47      */
     48     public static final int STYLE_SPINNER = 0;
     49 
     50     /** Creates a ProgressDialog with a horizontal progress bar.
     51      */
     52     public static final int STYLE_HORIZONTAL = 1;
     53 
     54     private ProgressBar mProgress;
     55     private TextView mMessageView;
     56 
     57     private int mProgressStyle = STYLE_SPINNER;
     58     private TextView mProgressNumber;
     59     private String mProgressNumberFormat;
     60     private TextView mProgressPercent;
     61     private NumberFormat mProgressPercentFormat;
     62 
     63     private int mMax;
     64     private int mProgressVal;
     65     private int mSecondaryProgressVal;
     66     private int mIncrementBy;
     67     private int mIncrementSecondaryBy;
     68     private Drawable mProgressDrawable;
     69     private Drawable mIndeterminateDrawable;
     70     private CharSequence mMessage;
     71     private boolean mIndeterminate;
     72 
     73     private boolean mHasStarted;
     74     private Handler mViewUpdateHandler;
     75 
     76     public ProgressDialog(Context context) {
     77         super(context);
     78         initFormats();
     79     }
     80 
     81     public ProgressDialog(Context context, int theme) {
     82         super(context, theme);
     83         initFormats();
     84     }
     85 
     86     private void initFormats() {
     87         mProgressNumberFormat = "%1d/%2d";
     88         mProgressPercentFormat = NumberFormat.getPercentInstance();
     89         mProgressPercentFormat.setMaximumFractionDigits(0);
     90     }
     91 
     92     public static ProgressDialog show(Context context, CharSequence title,
     93             CharSequence message) {
     94         return show(context, title, message, false);
     95     }
     96 
     97     public static ProgressDialog show(Context context, CharSequence title,
     98             CharSequence message, boolean indeterminate) {
     99         return show(context, title, message, indeterminate, false, null);
    100     }
    101 
    102     public static ProgressDialog show(Context context, CharSequence title,
    103             CharSequence message, boolean indeterminate, boolean cancelable) {
    104         return show(context, title, message, indeterminate, cancelable, null);
    105     }
    106 
    107     public static ProgressDialog show(Context context, CharSequence title,
    108             CharSequence message, boolean indeterminate,
    109             boolean cancelable, OnCancelListener cancelListener) {
    110         ProgressDialog dialog = new ProgressDialog(context);
    111         dialog.setTitle(title);
    112         dialog.setMessage(message);
    113         dialog.setIndeterminate(indeterminate);
    114         dialog.setCancelable(cancelable);
    115         dialog.setOnCancelListener(cancelListener);
    116         dialog.show();
    117         return dialog;
    118     }
    119 
    120     @Override
    121     protected void onCreate(Bundle savedInstanceState) {
    122         LayoutInflater inflater = LayoutInflater.from(mContext);
    123         TypedArray a = mContext.obtainStyledAttributes(null,
    124                 com.android.internal.R.styleable.AlertDialog,
    125                 com.android.internal.R.attr.alertDialogStyle, 0);
    126         if (mProgressStyle == STYLE_HORIZONTAL) {
    127 
    128             /* Use a separate handler to update the text views as they
    129              * must be updated on the same thread that created them.
    130              */
    131             mViewUpdateHandler = new Handler() {
    132                 @Override
    133                 public void handleMessage(Message msg) {
    134                     super.handleMessage(msg);
    135 
    136                     /* Update the number and percent */
    137                     int progress = mProgress.getProgress();
    138                     int max = mProgress.getMax();
    139                     if (mProgressNumberFormat != null) {
    140                         String format = mProgressNumberFormat;
    141                         mProgressNumber.setText(String.format(format, progress, max));
    142                     } else {
    143                         mProgressNumber.setText("");
    144                     }
    145                     if (mProgressPercentFormat != null) {
    146                         double percent = (double) progress / (double) max;
    147                         SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
    148                         tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
    149                                 0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    150                         mProgressPercent.setText(tmp);
    151                     } else {
    152                         mProgressPercent.setText("");
    153                     }
    154                 }
    155             };
    156             View view = inflater.inflate(a.getResourceId(
    157                     com.android.internal.R.styleable.AlertDialog_horizontalProgressLayout,
    158                     R.layout.alert_dialog_progress), null);
    159             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    160             mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
    161             mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
    162             setView(view);
    163         } else {
    164             View view = inflater.inflate(a.getResourceId(
    165                     com.android.internal.R.styleable.AlertDialog_progressLayout,
    166                     R.layout.progress_dialog), null);
    167             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    168             mMessageView = (TextView) view.findViewById(R.id.message);
    169             setView(view);
    170         }
    171         a.recycle();
    172         if (mMax > 0) {
    173             setMax(mMax);
    174         }
    175         if (mProgressVal > 0) {
    176             setProgress(mProgressVal);
    177         }
    178         if (mSecondaryProgressVal > 0) {
    179             setSecondaryProgress(mSecondaryProgressVal);
    180         }
    181         if (mIncrementBy > 0) {
    182             incrementProgressBy(mIncrementBy);
    183         }
    184         if (mIncrementSecondaryBy > 0) {
    185             incrementSecondaryProgressBy(mIncrementSecondaryBy);
    186         }
    187         if (mProgressDrawable != null) {
    188             setProgressDrawable(mProgressDrawable);
    189         }
    190         if (mIndeterminateDrawable != null) {
    191             setIndeterminateDrawable(mIndeterminateDrawable);
    192         }
    193         if (mMessage != null) {
    194             setMessage(mMessage);
    195         }
    196         setIndeterminate(mIndeterminate);
    197         onProgressChanged();
    198         super.onCreate(savedInstanceState);
    199     }
    200 
    201     @Override
    202     public void onStart() {
    203         super.onStart();
    204         mHasStarted = true;
    205     }
    206 
    207     @Override
    208     protected void onStop() {
    209         super.onStop();
    210         mHasStarted = false;
    211     }
    212 
    213     public void setProgress(int value) {
    214         if (mHasStarted) {
    215             mProgress.setProgress(value);
    216             onProgressChanged();
    217         } else {
    218             mProgressVal = value;
    219         }
    220     }
    221 
    222     public void setSecondaryProgress(int secondaryProgress) {
    223         if (mProgress != null) {
    224             mProgress.setSecondaryProgress(secondaryProgress);
    225             onProgressChanged();
    226         } else {
    227             mSecondaryProgressVal = secondaryProgress;
    228         }
    229     }
    230 
    231     public int getProgress() {
    232         if (mProgress != null) {
    233             return mProgress.getProgress();
    234         }
    235         return mProgressVal;
    236     }
    237 
    238     public int getSecondaryProgress() {
    239         if (mProgress != null) {
    240             return mProgress.getSecondaryProgress();
    241         }
    242         return mSecondaryProgressVal;
    243     }
    244 
    245     public int getMax() {
    246         if (mProgress != null) {
    247             return mProgress.getMax();
    248         }
    249         return mMax;
    250     }
    251 
    252     public void setMax(int max) {
    253         if (mProgress != null) {
    254             mProgress.setMax(max);
    255             onProgressChanged();
    256         } else {
    257             mMax = max;
    258         }
    259     }
    260 
    261     public void incrementProgressBy(int diff) {
    262         if (mProgress != null) {
    263             mProgress.incrementProgressBy(diff);
    264             onProgressChanged();
    265         } else {
    266             mIncrementBy += diff;
    267         }
    268     }
    269 
    270     public void incrementSecondaryProgressBy(int diff) {
    271         if (mProgress != null) {
    272             mProgress.incrementSecondaryProgressBy(diff);
    273             onProgressChanged();
    274         } else {
    275             mIncrementSecondaryBy += diff;
    276         }
    277     }
    278 
    279     public void setProgressDrawable(Drawable d) {
    280         if (mProgress != null) {
    281             mProgress.setProgressDrawable(d);
    282         } else {
    283             mProgressDrawable = d;
    284         }
    285     }
    286 
    287     public void setIndeterminateDrawable(Drawable d) {
    288         if (mProgress != null) {
    289             mProgress.setIndeterminateDrawable(d);
    290         } else {
    291             mIndeterminateDrawable = d;
    292         }
    293     }
    294 
    295     public void setIndeterminate(boolean indeterminate) {
    296         if (mProgress != null) {
    297             mProgress.setIndeterminate(indeterminate);
    298         } else {
    299             mIndeterminate = indeterminate;
    300         }
    301     }
    302 
    303     public boolean isIndeterminate() {
    304         if (mProgress != null) {
    305             return mProgress.isIndeterminate();
    306         }
    307         return mIndeterminate;
    308     }
    309 
    310     @Override
    311     public void setMessage(CharSequence message) {
    312         if (mProgress != null) {
    313             if (mProgressStyle == STYLE_HORIZONTAL) {
    314                 super.setMessage(message);
    315             } else {
    316                 mMessageView.setText(message);
    317             }
    318         } else {
    319             mMessage = message;
    320         }
    321     }
    322 
    323     public void setProgressStyle(int style) {
    324         mProgressStyle = style;
    325     }
    326 
    327     /**
    328      * Change the format of the small text showing current and maximum units
    329      * of progress.  The default is "%1d/%2d".
    330      * Should not be called during the number is progressing.
    331      * @param format A string passed to {@link String#format String.format()};
    332      * use "%1d" for the current number and "%2d" for the maximum.  If null,
    333      * nothing will be shown.
    334      */
    335     public void setProgressNumberFormat(String format) {
    336         mProgressNumberFormat = format;
    337         onProgressChanged();
    338     }
    339 
    340     /**
    341      * Change the format of the small text showing the percentage of progress.
    342      * The default is
    343      * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
    344      * Should not be called during the number is progressing.
    345      * @param format An instance of a {@link NumberFormat} to generate the
    346      * percentage text.  If null, nothing will be shown.
    347      */
    348     public void setProgressPercentFormat(NumberFormat format) {
    349         mProgressPercentFormat = format;
    350         onProgressChanged();
    351     }
    352 
    353     private void onProgressChanged() {
    354         if (mProgressStyle == STYLE_HORIZONTAL) {
    355             if (mViewUpdateHandler != null && !mViewUpdateHandler.hasMessages(0)) {
    356                 mViewUpdateHandler.sendEmptyMessage(0);
    357             }
    358         }
    359     }
    360 }
    361