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