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 android.content.Context;
     20 import android.graphics.drawable.Drawable;
     21 import android.os.Bundle;
     22 import android.os.Handler;
     23 import android.os.Message;
     24 import android.text.Spannable;
     25 import android.text.SpannableString;
     26 import android.text.style.StyleSpan;
     27 import android.view.LayoutInflater;
     28 import android.view.View;
     29 import android.widget.ProgressBar;
     30 import android.widget.TextView;
     31 
     32 import com.android.internal.R;
     33 
     34 import java.text.NumberFormat;
     35 
     36 /**
     37  * <p>A dialog showing a progress indicator and an optional text message or view.
     38  * Only a text message or a view can be used at the same time.</p>
     39  * <p>The dialog can be made cancelable on back key press.</p>
     40  * <p>The progress range is 0..10000.</p>
     41  */
     42 public class ProgressDialog extends AlertDialog {
     43 
     44     /** Creates a ProgressDialog with a ciruclar, spinning progress
     45      * bar. This is the default.
     46      */
     47     public static final int STYLE_SPINNER = 0;
     48 
     49     /** Creates a ProgressDialog with a horizontal progress bar.
     50      */
     51     public static final int STYLE_HORIZONTAL = 1;
     52 
     53     private ProgressBar mProgress;
     54     private TextView mMessageView;
     55 
     56     private int mProgressStyle = STYLE_SPINNER;
     57     private TextView mProgressNumber;
     58     private String mProgressNumberFormat;
     59     private TextView mProgressPercent;
     60     private NumberFormat mProgressPercentFormat;
     61 
     62     private int mMax;
     63     private int mProgressVal;
     64     private int mSecondaryProgressVal;
     65     private int mIncrementBy;
     66     private int mIncrementSecondaryBy;
     67     private Drawable mProgressDrawable;
     68     private Drawable mIndeterminateDrawable;
     69     private CharSequence mMessage;
     70     private boolean mIndeterminate;
     71 
     72     private boolean mHasStarted;
     73     private Handler mViewUpdateHandler;
     74 
     75     public ProgressDialog(Context context) {
     76         this(context, com.android.internal.R.style.Theme_Dialog_Alert);
     77     }
     78 
     79     public ProgressDialog(Context context, int theme) {
     80         super(context, theme);
     81     }
     82 
     83     public static ProgressDialog show(Context context, CharSequence title,
     84             CharSequence message) {
     85         return show(context, title, message, false);
     86     }
     87 
     88     public static ProgressDialog show(Context context, CharSequence title,
     89             CharSequence message, boolean indeterminate) {
     90         return show(context, title, message, indeterminate, false, null);
     91     }
     92 
     93     public static ProgressDialog show(Context context, CharSequence title,
     94             CharSequence message, boolean indeterminate, boolean cancelable) {
     95         return show(context, title, message, indeterminate, cancelable, null);
     96     }
     97 
     98     public static ProgressDialog show(Context context, CharSequence title,
     99             CharSequence message, boolean indeterminate,
    100             boolean cancelable, OnCancelListener cancelListener) {
    101         ProgressDialog dialog = new ProgressDialog(context);
    102         dialog.setTitle(title);
    103         dialog.setMessage(message);
    104         dialog.setIndeterminate(indeterminate);
    105         dialog.setCancelable(cancelable);
    106         dialog.setOnCancelListener(cancelListener);
    107         dialog.show();
    108         return dialog;
    109     }
    110 
    111     @Override
    112     protected void onCreate(Bundle savedInstanceState) {
    113         LayoutInflater inflater = LayoutInflater.from(mContext);
    114         if (mProgressStyle == STYLE_HORIZONTAL) {
    115 
    116             /* Use a separate handler to update the text views as they
    117              * must be updated on the same thread that created them.
    118              */
    119             mViewUpdateHandler = new Handler() {
    120                 @Override
    121                 public void handleMessage(Message msg) {
    122                     super.handleMessage(msg);
    123 
    124                     /* Update the number and percent */
    125                     int progress = mProgress.getProgress();
    126                     int max = mProgress.getMax();
    127                     double percent = (double) progress / (double) max;
    128                     String format = mProgressNumberFormat;
    129                     mProgressNumber.setText(String.format(format, progress, max));
    130                     SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
    131                     tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
    132                             0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    133                     mProgressPercent.setText(tmp);
    134                 }
    135             };
    136             View view = inflater.inflate(R.layout.alert_dialog_progress, null);
    137             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    138             mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
    139             mProgressNumberFormat = "%d/%d";
    140             mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
    141             mProgressPercentFormat = NumberFormat.getPercentInstance();
    142             mProgressPercentFormat.setMaximumFractionDigits(0);
    143             setView(view);
    144         } else {
    145             View view = inflater.inflate(R.layout.progress_dialog, null);
    146             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    147             mMessageView = (TextView) view.findViewById(R.id.message);
    148             setView(view);
    149         }
    150         if (mMax > 0) {
    151             setMax(mMax);
    152         }
    153         if (mProgressVal > 0) {
    154             setProgress(mProgressVal);
    155         }
    156         if (mSecondaryProgressVal > 0) {
    157             setSecondaryProgress(mSecondaryProgressVal);
    158         }
    159         if (mIncrementBy > 0) {
    160             incrementProgressBy(mIncrementBy);
    161         }
    162         if (mIncrementSecondaryBy > 0) {
    163             incrementSecondaryProgressBy(mIncrementSecondaryBy);
    164         }
    165         if (mProgressDrawable != null) {
    166             setProgressDrawable(mProgressDrawable);
    167         }
    168         if (mIndeterminateDrawable != null) {
    169             setIndeterminateDrawable(mIndeterminateDrawable);
    170         }
    171         if (mMessage != null) {
    172             setMessage(mMessage);
    173         }
    174         setIndeterminate(mIndeterminate);
    175         onProgressChanged();
    176         super.onCreate(savedInstanceState);
    177     }
    178 
    179     @Override
    180     public void onStart() {
    181         super.onStart();
    182         mHasStarted = true;
    183     }
    184 
    185     @Override
    186     protected void onStop() {
    187         super.onStop();
    188         mHasStarted = false;
    189     }
    190 
    191     public void setProgress(int value) {
    192         if (mHasStarted) {
    193             mProgress.setProgress(value);
    194             onProgressChanged();
    195         } else {
    196             mProgressVal = value;
    197         }
    198     }
    199 
    200     public void setSecondaryProgress(int secondaryProgress) {
    201         if (mProgress != null) {
    202             mProgress.setSecondaryProgress(secondaryProgress);
    203             onProgressChanged();
    204         } else {
    205             mSecondaryProgressVal = secondaryProgress;
    206         }
    207     }
    208 
    209     public int getProgress() {
    210         if (mProgress != null) {
    211             return mProgress.getProgress();
    212         }
    213         return mProgressVal;
    214     }
    215 
    216     public int getSecondaryProgress() {
    217         if (mProgress != null) {
    218             return mProgress.getSecondaryProgress();
    219         }
    220         return mSecondaryProgressVal;
    221     }
    222 
    223     public int getMax() {
    224         if (mProgress != null) {
    225             return mProgress.getMax();
    226         }
    227         return mMax;
    228     }
    229 
    230     public void setMax(int max) {
    231         if (mProgress != null) {
    232             mProgress.setMax(max);
    233             onProgressChanged();
    234         } else {
    235             mMax = max;
    236         }
    237     }
    238 
    239     public void incrementProgressBy(int diff) {
    240         if (mProgress != null) {
    241             mProgress.incrementProgressBy(diff);
    242             onProgressChanged();
    243         } else {
    244             mIncrementBy += diff;
    245         }
    246     }
    247 
    248     public void incrementSecondaryProgressBy(int diff) {
    249         if (mProgress != null) {
    250             mProgress.incrementSecondaryProgressBy(diff);
    251             onProgressChanged();
    252         } else {
    253             mIncrementSecondaryBy += diff;
    254         }
    255     }
    256 
    257     public void setProgressDrawable(Drawable d) {
    258         if (mProgress != null) {
    259             mProgress.setProgressDrawable(d);
    260         } else {
    261             mProgressDrawable = d;
    262         }
    263     }
    264 
    265     public void setIndeterminateDrawable(Drawable d) {
    266         if (mProgress != null) {
    267             mProgress.setIndeterminateDrawable(d);
    268         } else {
    269             mIndeterminateDrawable = d;
    270         }
    271     }
    272 
    273     public void setIndeterminate(boolean indeterminate) {
    274         if (mProgress != null) {
    275             mProgress.setIndeterminate(indeterminate);
    276         } else {
    277             mIndeterminate = indeterminate;
    278         }
    279     }
    280 
    281     public boolean isIndeterminate() {
    282         if (mProgress != null) {
    283             return mProgress.isIndeterminate();
    284         }
    285         return mIndeterminate;
    286     }
    287 
    288     @Override
    289     public void setMessage(CharSequence message) {
    290         if (mProgress != null) {
    291             if (mProgressStyle == STYLE_HORIZONTAL) {
    292                 super.setMessage(message);
    293             } else {
    294                 mMessageView.setText(message);
    295             }
    296         } else {
    297             mMessage = message;
    298         }
    299     }
    300 
    301     public void setProgressStyle(int style) {
    302         mProgressStyle = style;
    303     }
    304 
    305     /**
    306      * Change the format of Progress Number. The default is "current/max".
    307      * Should not be called during the number is progressing.
    308      * @param format Should contain two "%d". The first is used for current number
    309      * and the second is used for the maximum.
    310      * @hide
    311      */
    312     public void setProgressNumberFormat(String format) {
    313         mProgressNumberFormat = format;
    314     }
    315 
    316     private void onProgressChanged() {
    317         if (mProgressStyle == STYLE_HORIZONTAL) {
    318             mViewUpdateHandler.sendEmptyMessage(0);
    319         }
    320     }
    321 }
    322