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