ProgressDialog.java revision 5d4faa91f7e3135d62f9cef730cbe876074937ee
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 17package android.app; 18 19import android.content.Context; 20import android.graphics.drawable.Drawable; 21import android.os.Bundle; 22import android.os.Handler; 23import android.os.Message; 24import android.text.Spannable; 25import android.text.SpannableString; 26import android.text.style.StyleSpan; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.widget.ProgressBar; 30import android.widget.TextView; 31 32import com.android.internal.R; 33 34import 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 */ 42public class ProgressDialog extends AlertDialog { 43 44 /** Creates a ProgressDialog with a circular, 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 super(context); 77 initFormats(); 78 } 79 80 public ProgressDialog(Context context, int theme) { 81 super(context, theme); 82 initFormats(); 83 } 84 85 private void initFormats() { 86 mProgressNumberFormat = "%1d/%2d"; 87 mProgressPercentFormat = NumberFormat.getPercentInstance(); 88 mProgressPercentFormat.setMaximumFractionDigits(0); 89 } 90 91 public static ProgressDialog show(Context context, CharSequence title, 92 CharSequence message) { 93 return show(context, title, message, false); 94 } 95 96 public static ProgressDialog show(Context context, CharSequence title, 97 CharSequence message, boolean indeterminate) { 98 return show(context, title, message, indeterminate, false, null); 99 } 100 101 public static ProgressDialog show(Context context, CharSequence title, 102 CharSequence message, boolean indeterminate, boolean cancelable) { 103 return show(context, title, message, indeterminate, cancelable, null); 104 } 105 106 public static ProgressDialog show(Context context, CharSequence title, 107 CharSequence message, boolean indeterminate, 108 boolean cancelable, OnCancelListener cancelListener) { 109 ProgressDialog dialog = new ProgressDialog(context); 110 dialog.setTitle(title); 111 dialog.setMessage(message); 112 dialog.setIndeterminate(indeterminate); 113 dialog.setCancelable(cancelable); 114 dialog.setOnCancelListener(cancelListener); 115 dialog.show(); 116 return dialog; 117 } 118 119 @Override 120 protected void onCreate(Bundle savedInstanceState) { 121 LayoutInflater inflater = LayoutInflater.from(mContext); 122 if (mProgressStyle == STYLE_HORIZONTAL) { 123 124 /* Use a separate handler to update the text views as they 125 * must be updated on the same thread that created them. 126 */ 127 mViewUpdateHandler = new Handler() { 128 @Override 129 public void handleMessage(Message msg) { 130 super.handleMessage(msg); 131 132 /* Update the number and percent */ 133 int progress = mProgress.getProgress(); 134 int max = mProgress.getMax(); 135 if (mProgressNumberFormat != null) { 136 String format = mProgressNumberFormat; 137 mProgressNumber.setText(String.format(format, progress, max)); 138 } else { 139 mProgressNumber.setText(""); 140 } 141 if (mProgressPercentFormat != null) { 142 double percent = (double) progress / (double) max; 143 SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent)); 144 tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 145 0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 146 mProgressPercent.setText(tmp); 147 } else { 148 mProgressPercent.setText(""); 149 } 150 } 151 }; 152 View view = inflater.inflate(R.layout.alert_dialog_progress, null); 153 mProgress = (ProgressBar) view.findViewById(R.id.progress); 154 mProgressNumber = (TextView) view.findViewById(R.id.progress_number); 155 mProgressPercent = (TextView) view.findViewById(R.id.progress_percent); 156 setView(view); 157 } else { 158 View view = inflater.inflate(R.layout.progress_dialog, null); 159 mProgress = (ProgressBar) view.findViewById(R.id.progress); 160 mMessageView = (TextView) view.findViewById(R.id.message); 161 setView(view); 162 } 163 if (mMax > 0) { 164 setMax(mMax); 165 } 166 if (mProgressVal > 0) { 167 setProgress(mProgressVal); 168 } 169 if (mSecondaryProgressVal > 0) { 170 setSecondaryProgress(mSecondaryProgressVal); 171 } 172 if (mIncrementBy > 0) { 173 incrementProgressBy(mIncrementBy); 174 } 175 if (mIncrementSecondaryBy > 0) { 176 incrementSecondaryProgressBy(mIncrementSecondaryBy); 177 } 178 if (mProgressDrawable != null) { 179 setProgressDrawable(mProgressDrawable); 180 } 181 if (mIndeterminateDrawable != null) { 182 setIndeterminateDrawable(mIndeterminateDrawable); 183 } 184 if (mMessage != null) { 185 setMessage(mMessage); 186 } 187 setIndeterminate(mIndeterminate); 188 onProgressChanged(); 189 super.onCreate(savedInstanceState); 190 } 191 192 @Override 193 public void onStart() { 194 super.onStart(); 195 mHasStarted = true; 196 } 197 198 @Override 199 protected void onStop() { 200 super.onStop(); 201 mHasStarted = false; 202 } 203 204 public void setProgress(int value) { 205 if (mHasStarted) { 206 mProgress.setProgress(value); 207 onProgressChanged(); 208 } else { 209 mProgressVal = value; 210 } 211 } 212 213 public void setSecondaryProgress(int secondaryProgress) { 214 if (mProgress != null) { 215 mProgress.setSecondaryProgress(secondaryProgress); 216 onProgressChanged(); 217 } else { 218 mSecondaryProgressVal = secondaryProgress; 219 } 220 } 221 222 public int getProgress() { 223 if (mProgress != null) { 224 return mProgress.getProgress(); 225 } 226 return mProgressVal; 227 } 228 229 public int getSecondaryProgress() { 230 if (mProgress != null) { 231 return mProgress.getSecondaryProgress(); 232 } 233 return mSecondaryProgressVal; 234 } 235 236 public int getMax() { 237 if (mProgress != null) { 238 return mProgress.getMax(); 239 } 240 return mMax; 241 } 242 243 public void setMax(int max) { 244 if (mProgress != null) { 245 mProgress.setMax(max); 246 onProgressChanged(); 247 } else { 248 mMax = max; 249 } 250 } 251 252 public void incrementProgressBy(int diff) { 253 if (mProgress != null) { 254 mProgress.incrementProgressBy(diff); 255 onProgressChanged(); 256 } else { 257 mIncrementBy += diff; 258 } 259 } 260 261 public void incrementSecondaryProgressBy(int diff) { 262 if (mProgress != null) { 263 mProgress.incrementSecondaryProgressBy(diff); 264 onProgressChanged(); 265 } else { 266 mIncrementSecondaryBy += diff; 267 } 268 } 269 270 public void setProgressDrawable(Drawable d) { 271 if (mProgress != null) { 272 mProgress.setProgressDrawable(d); 273 } else { 274 mProgressDrawable = d; 275 } 276 } 277 278 public void setIndeterminateDrawable(Drawable d) { 279 if (mProgress != null) { 280 mProgress.setIndeterminateDrawable(d); 281 } else { 282 mIndeterminateDrawable = d; 283 } 284 } 285 286 public void setIndeterminate(boolean indeterminate) { 287 if (mProgress != null) { 288 mProgress.setIndeterminate(indeterminate); 289 } else { 290 mIndeterminate = indeterminate; 291 } 292 } 293 294 public boolean isIndeterminate() { 295 if (mProgress != null) { 296 return mProgress.isIndeterminate(); 297 } 298 return mIndeterminate; 299 } 300 301 @Override 302 public void setMessage(CharSequence message) { 303 if (mProgress != null) { 304 if (mProgressStyle == STYLE_HORIZONTAL) { 305 super.setMessage(message); 306 } else { 307 mMessageView.setText(message); 308 } 309 } else { 310 mMessage = message; 311 } 312 } 313 314 public void setProgressStyle(int style) { 315 mProgressStyle = style; 316 } 317 318 /** 319 * Change the format of the small text showing current and maximum units 320 * of progress. The default is "%1d/%2d". 321 * Should not be called during the number is progressing. 322 * @param format A string passed to {@link String#format String.format()}; 323 * use "%1d" for the current number and "%2d" for the maximum. If null, 324 * nothing will be shown. 325 */ 326 public void setProgressNumberFormat(String format) { 327 mProgressNumberFormat = format; 328 onProgressChanged(); 329 } 330 331 /** 332 * Change the format of the small text showing the percentage of progress. 333 * The default is 334 * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().} 335 * Should not be called during the number is progressing. 336 * @param format An instance of a {@link NumberFormat} to generate the 337 * percentage text. If null, nothing will be shown. 338 */ 339 public void setProgressPercentFormat(NumberFormat format) { 340 mProgressPercentFormat = format; 341 onProgressChanged(); 342 } 343 344 private void onProgressChanged() { 345 if (mProgressStyle == STYLE_HORIZONTAL) { 346 if (mViewUpdateHandler != null && !mViewUpdateHandler.hasMessages(0)) { 347 mViewUpdateHandler.sendEmptyMessage(0); 348 } 349 } 350 } 351} 352