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.annotation.UnsupportedAppUsage;
     22 import android.content.Context;
     23 import android.content.res.TypedArray;
     24 import android.graphics.drawable.Drawable;
     25 import android.os.Build;
     26 import android.os.Bundle;
     27 import android.os.Handler;
     28 import android.os.Message;
     29 import android.text.Spannable;
     30 import android.text.SpannableString;
     31 import android.text.style.StyleSpan;
     32 import android.view.LayoutInflater;
     33 import android.view.View;
     34 import android.widget.ProgressBar;
     35 import android.widget.TextView;
     36 
     37 import java.text.NumberFormat;
     38 
     39 /**
     40  * A dialog showing a progress indicator and an optional text message or view.
     41  * Only a text message or a view can be used at the same time.
     42  *
     43  * <p>The dialog can be made cancelable on back key press.</p>
     44  *
     45  * <p>The progress range is 0 to {@link #getMax() max}.</p>
     46  *
     47  * @deprecated <code>ProgressDialog</code> is a modal dialog, which prevents the
     48  * user from interacting with the app. Instead of using this class, you should
     49  * use a progress indicator like {@link android.widget.ProgressBar}, which can
     50  * be embedded in your app's UI. Alternatively, you can use a
     51  * <a href="/guide/topics/ui/notifiers/notifications.html">notification</a>
     52  * to inform the user of the task's progress.
     53  */
     54 @Deprecated
     55 public class ProgressDialog extends AlertDialog {
     56 
     57     /**
     58      * Creates a ProgressDialog with a circular, spinning progress
     59      * bar. This is the default.
     60      */
     61     public static final int STYLE_SPINNER = 0;
     62 
     63     /**
     64      * Creates a ProgressDialog with a horizontal progress bar.
     65      */
     66     public static final int STYLE_HORIZONTAL = 1;
     67 
     68     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     69     private ProgressBar mProgress;
     70     @UnsupportedAppUsage
     71     private TextView mMessageView;
     72 
     73     private int mProgressStyle = STYLE_SPINNER;
     74     @UnsupportedAppUsage
     75     private TextView mProgressNumber;
     76     private String mProgressNumberFormat;
     77     private TextView mProgressPercent;
     78     private NumberFormat mProgressPercentFormat;
     79 
     80     private int mMax;
     81     private int mProgressVal;
     82     private int mSecondaryProgressVal;
     83     private int mIncrementBy;
     84     private int mIncrementSecondaryBy;
     85     private Drawable mProgressDrawable;
     86     private Drawable mIndeterminateDrawable;
     87     private CharSequence mMessage;
     88     private boolean mIndeterminate;
     89 
     90     private boolean mHasStarted;
     91     private Handler mViewUpdateHandler;
     92 
     93     /**
     94      * Creates a Progress dialog.
     95      *
     96      * @param context the parent context
     97      */
     98     public ProgressDialog(Context context) {
     99         super(context);
    100         initFormats();
    101     }
    102 
    103     /**
    104      * Creates a Progress dialog.
    105      *
    106      * @param context the parent context
    107      * @param theme the resource ID of the theme against which to inflate
    108      *              this dialog, or {@code 0} to use the parent
    109      *              {@code context}'s default alert dialog theme
    110      */
    111     public ProgressDialog(Context context, int theme) {
    112         super(context, theme);
    113         initFormats();
    114     }
    115 
    116     private void initFormats() {
    117         mProgressNumberFormat = "%1d/%2d";
    118         mProgressPercentFormat = NumberFormat.getPercentInstance();
    119         mProgressPercentFormat.setMaximumFractionDigits(0);
    120     }
    121 
    122     /**
    123      * Creates and shows a ProgressDialog.
    124      *
    125      * @param context the parent context
    126      * @param title the title text for the dialog's window
    127      * @param message the text to be displayed in the dialog
    128      * @return the ProgressDialog
    129      */
    130     public static ProgressDialog show(Context context, CharSequence title,
    131             CharSequence message) {
    132         return show(context, title, message, false);
    133     }
    134 
    135     /**
    136      * Creates and shows a ProgressDialog.
    137      *
    138      * @param context the parent context
    139      * @param title the title text for the dialog's window
    140      * @param message the text to be displayed in the dialog
    141      * @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
    142      *        indeterminate}, false otherwise
    143      * @return the ProgressDialog
    144      */
    145     public static ProgressDialog show(Context context, CharSequence title,
    146             CharSequence message, boolean indeterminate) {
    147         return show(context, title, message, indeterminate, false, null);
    148     }
    149 
    150     /**
    151      * Creates and shows a ProgressDialog.
    152      *
    153      * @param context the parent context
    154      * @param title the title text for the dialog's window
    155      * @param message the text to be displayed in the dialog
    156      * @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
    157      *        indeterminate}, false otherwise
    158      * @param cancelable true if the dialog is {@link #setCancelable(boolean) cancelable},
    159      *        false otherwise
    160      * @return the ProgressDialog
    161      */
    162     public static ProgressDialog show(Context context, CharSequence title,
    163             CharSequence message, boolean indeterminate, boolean cancelable) {
    164         return show(context, title, message, indeterminate, cancelable, null);
    165     }
    166 
    167     /**
    168      * Creates and shows a ProgressDialog.
    169      *
    170      * @param context the parent context
    171      * @param title the title text for the dialog's window
    172      * @param message the text to be displayed in the dialog
    173      * @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
    174      *        indeterminate}, false otherwise
    175      * @param cancelable true if the dialog is {@link #setCancelable(boolean) cancelable},
    176      *        false otherwise
    177      * @param cancelListener the {@link #setOnCancelListener(OnCancelListener) listener}
    178      *        to be invoked when the dialog is canceled
    179      * @return the ProgressDialog
    180      */
    181     public static ProgressDialog show(Context context, CharSequence title,
    182             CharSequence message, boolean indeterminate,
    183             boolean cancelable, OnCancelListener cancelListener) {
    184         ProgressDialog dialog = new ProgressDialog(context);
    185         dialog.setTitle(title);
    186         dialog.setMessage(message);
    187         dialog.setIndeterminate(indeterminate);
    188         dialog.setCancelable(cancelable);
    189         dialog.setOnCancelListener(cancelListener);
    190         dialog.show();
    191         return dialog;
    192     }
    193 
    194     @Override
    195     protected void onCreate(Bundle savedInstanceState) {
    196         LayoutInflater inflater = LayoutInflater.from(mContext);
    197         TypedArray a = mContext.obtainStyledAttributes(null,
    198                 com.android.internal.R.styleable.AlertDialog,
    199                 com.android.internal.R.attr.alertDialogStyle, 0);
    200         if (mProgressStyle == STYLE_HORIZONTAL) {
    201 
    202             /* Use a separate handler to update the text views as they
    203              * must be updated on the same thread that created them.
    204              */
    205             mViewUpdateHandler = new Handler() {
    206                 @Override
    207                 public void handleMessage(Message msg) {
    208                     super.handleMessage(msg);
    209 
    210                     /* Update the number and percent */
    211                     int progress = mProgress.getProgress();
    212                     int max = mProgress.getMax();
    213                     if (mProgressNumberFormat != null) {
    214                         String format = mProgressNumberFormat;
    215                         mProgressNumber.setText(String.format(format, progress, max));
    216                     } else {
    217                         mProgressNumber.setText("");
    218                     }
    219                     if (mProgressPercentFormat != null) {
    220                         double percent = (double) progress / (double) max;
    221                         SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
    222                         tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
    223                                 0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    224                         mProgressPercent.setText(tmp);
    225                     } else {
    226                         mProgressPercent.setText("");
    227                     }
    228                 }
    229             };
    230             View view = inflater.inflate(a.getResourceId(
    231                     com.android.internal.R.styleable.AlertDialog_horizontalProgressLayout,
    232                     R.layout.alert_dialog_progress), null);
    233             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    234             mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
    235             mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
    236             setView(view);
    237         } else {
    238             View view = inflater.inflate(a.getResourceId(
    239                     com.android.internal.R.styleable.AlertDialog_progressLayout,
    240                     R.layout.progress_dialog), null);
    241             mProgress = (ProgressBar) view.findViewById(R.id.progress);
    242             mMessageView = (TextView) view.findViewById(R.id.message);
    243             setView(view);
    244         }
    245         a.recycle();
    246         if (mMax > 0) {
    247             setMax(mMax);
    248         }
    249         if (mProgressVal > 0) {
    250             setProgress(mProgressVal);
    251         }
    252         if (mSecondaryProgressVal > 0) {
    253             setSecondaryProgress(mSecondaryProgressVal);
    254         }
    255         if (mIncrementBy > 0) {
    256             incrementProgressBy(mIncrementBy);
    257         }
    258         if (mIncrementSecondaryBy > 0) {
    259             incrementSecondaryProgressBy(mIncrementSecondaryBy);
    260         }
    261         if (mProgressDrawable != null) {
    262             setProgressDrawable(mProgressDrawable);
    263         }
    264         if (mIndeterminateDrawable != null) {
    265             setIndeterminateDrawable(mIndeterminateDrawable);
    266         }
    267         if (mMessage != null) {
    268             setMessage(mMessage);
    269         }
    270         setIndeterminate(mIndeterminate);
    271         onProgressChanged();
    272         super.onCreate(savedInstanceState);
    273     }
    274 
    275     @Override
    276     public void onStart() {
    277         super.onStart();
    278         mHasStarted = true;
    279     }
    280 
    281     @Override
    282     protected void onStop() {
    283         super.onStop();
    284         mHasStarted = false;
    285     }
    286 
    287     /**
    288      * Sets the current progress.
    289      *
    290      * @param value the current progress, a value between 0 and {@link #getMax()}
    291      *
    292      * @see ProgressBar#setProgress(int)
    293      */
    294     public void setProgress(int value) {
    295         if (mHasStarted) {
    296             mProgress.setProgress(value);
    297             onProgressChanged();
    298         } else {
    299             mProgressVal = value;
    300         }
    301     }
    302 
    303     /**
    304      * Sets the secondary progress.
    305      *
    306      * @param secondaryProgress the current secondary progress, a value between 0 and
    307      * {@link #getMax()}
    308      *
    309      * @see ProgressBar#setSecondaryProgress(int)
    310      */
    311     public void setSecondaryProgress(int secondaryProgress) {
    312         if (mProgress != null) {
    313             mProgress.setSecondaryProgress(secondaryProgress);
    314             onProgressChanged();
    315         } else {
    316             mSecondaryProgressVal = secondaryProgress;
    317         }
    318     }
    319 
    320     /**
    321      * Gets the current progress.
    322      *
    323      * @return the current progress, a value between 0 and {@link #getMax()}
    324      */
    325     public int getProgress() {
    326         if (mProgress != null) {
    327             return mProgress.getProgress();
    328         }
    329         return mProgressVal;
    330     }
    331 
    332     /**
    333      * Gets the current secondary progress.
    334      *
    335      * @return the current secondary progress, a value between 0 and {@link #getMax()}
    336      */
    337     public int getSecondaryProgress() {
    338         if (mProgress != null) {
    339             return mProgress.getSecondaryProgress();
    340         }
    341         return mSecondaryProgressVal;
    342     }
    343 
    344     /**
    345      * Gets the maximum allowed progress value. The default value is 100.
    346      *
    347      * @return the maximum value
    348      */
    349     public int getMax() {
    350         if (mProgress != null) {
    351             return mProgress.getMax();
    352         }
    353         return mMax;
    354     }
    355 
    356     /**
    357      * Sets the maximum allowed progress value.
    358      */
    359     public void setMax(int max) {
    360         if (mProgress != null) {
    361             mProgress.setMax(max);
    362             onProgressChanged();
    363         } else {
    364             mMax = max;
    365         }
    366     }
    367 
    368     /**
    369      * Increments the current progress value.
    370      *
    371      * @param diff the amount by which the current progress will be incremented,
    372      * up to {@link #getMax()}
    373      */
    374     public void incrementProgressBy(int diff) {
    375         if (mProgress != null) {
    376             mProgress.incrementProgressBy(diff);
    377             onProgressChanged();
    378         } else {
    379             mIncrementBy += diff;
    380         }
    381     }
    382 
    383     /**
    384      * Increments the current secondary progress value.
    385      *
    386      * @param diff the amount by which the current secondary progress will be incremented,
    387      * up to {@link #getMax()}
    388      */
    389     public void incrementSecondaryProgressBy(int diff) {
    390         if (mProgress != null) {
    391             mProgress.incrementSecondaryProgressBy(diff);
    392             onProgressChanged();
    393         } else {
    394             mIncrementSecondaryBy += diff;
    395         }
    396     }
    397 
    398     /**
    399      * Sets the drawable to be used to display the progress value.
    400      *
    401      * @param d the drawable to be used
    402      *
    403      * @see ProgressBar#setProgressDrawable(Drawable)
    404      */
    405     public void setProgressDrawable(Drawable d) {
    406         if (mProgress != null) {
    407             mProgress.setProgressDrawable(d);
    408         } else {
    409             mProgressDrawable = d;
    410         }
    411     }
    412 
    413     /**
    414      * Sets the drawable to be used to display the indeterminate progress value.
    415      *
    416      * @param d the drawable to be used
    417      *
    418      * @see ProgressBar#setProgressDrawable(Drawable)
    419      * @see #setIndeterminate(boolean)
    420      */
    421     public void setIndeterminateDrawable(Drawable d) {
    422         if (mProgress != null) {
    423             mProgress.setIndeterminateDrawable(d);
    424         } else {
    425             mIndeterminateDrawable = d;
    426         }
    427     }
    428 
    429     /**
    430      * Change the indeterminate mode for this ProgressDialog. In indeterminate
    431      * mode, the progress is ignored and the dialog shows an infinite
    432      * animation instead.
    433      *
    434      * <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
    435      * is always indeterminate and will ignore this setting.</p>
    436      *
    437      * @param indeterminate true to enable indeterminate mode, false otherwise
    438      *
    439      * @see #setProgressStyle(int)
    440      */
    441     public void setIndeterminate(boolean indeterminate) {
    442         if (mProgress != null) {
    443             mProgress.setIndeterminate(indeterminate);
    444         } else {
    445             mIndeterminate = indeterminate;
    446         }
    447     }
    448 
    449     /**
    450      * Whether this ProgressDialog is in indeterminate mode.
    451      *
    452      * @return true if the dialog is in indeterminate mode, false otherwise
    453      */
    454     public boolean isIndeterminate() {
    455         if (mProgress != null) {
    456             return mProgress.isIndeterminate();
    457         }
    458         return mIndeterminate;
    459     }
    460 
    461     @Override
    462     public void setMessage(CharSequence message) {
    463         if (mProgress != null) {
    464             if (mProgressStyle == STYLE_HORIZONTAL) {
    465                 super.setMessage(message);
    466             } else {
    467                 mMessageView.setText(message);
    468             }
    469         } else {
    470             mMessage = message;
    471         }
    472     }
    473 
    474     /**
    475      * Sets the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
    476      * {@link #STYLE_HORIZONTAL}. The default is {@link #STYLE_SPINNER}.
    477      *
    478      * <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
    479      * is always indeterminate and will ignore the {@link #setIndeterminate(boolean)
    480      * indeterminate} setting.</p>
    481      *
    482      * @param style the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
    483      * {@link #STYLE_HORIZONTAL}
    484      */
    485     public void setProgressStyle(int style) {
    486         mProgressStyle = style;
    487     }
    488 
    489     /**
    490      * Change the format of the small text showing current and maximum units
    491      * of progress.  The default is "%1d/%2d".
    492      * Should not be called during the number is progressing.
    493      * @param format A string passed to {@link String#format String.format()};
    494      * use "%1d" for the current number and "%2d" for the maximum.  If null,
    495      * nothing will be shown.
    496      */
    497     public void setProgressNumberFormat(String format) {
    498         mProgressNumberFormat = format;
    499         onProgressChanged();
    500     }
    501 
    502     /**
    503      * Change the format of the small text showing the percentage of progress.
    504      * The default is
    505      * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
    506      * Should not be called during the number is progressing.
    507      * @param format An instance of a {@link NumberFormat} to generate the
    508      * percentage text.  If null, nothing will be shown.
    509      */
    510     public void setProgressPercentFormat(NumberFormat format) {
    511         mProgressPercentFormat = format;
    512         onProgressChanged();
    513     }
    514 
    515     private void onProgressChanged() {
    516         if (mProgressStyle == STYLE_HORIZONTAL) {
    517             if (mViewUpdateHandler != null && !mViewUpdateHandler.hasMessages(0)) {
    518                 mViewUpdateHandler.sendEmptyMessage(0);
    519             }
    520         }
    521     }
    522 }
    523