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 ProgressDialog(Context context)75 public ProgressDialog(Context context) { 76 this(context, com.android.internal.R.style.Theme_Dialog_Alert); 77 } 78 ProgressDialog(Context context, int theme)79 public ProgressDialog(Context context, int theme) { 80 super(context, theme); 81 } 82 show(Context context, CharSequence title, CharSequence message)83 public static ProgressDialog show(Context context, CharSequence title, 84 CharSequence message) { 85 return show(context, title, message, false); 86 } 87 show(Context context, CharSequence title, CharSequence message, boolean indeterminate)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 show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable)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 show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable, OnCancelListener cancelListener)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 onCreate(Bundle savedInstanceState)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 onStart()180 public void onStart() { 181 super.onStart(); 182 mHasStarted = true; 183 } 184 185 @Override onStop()186 protected void onStop() { 187 super.onStop(); 188 mHasStarted = false; 189 } 190 setProgress(int value)191 public void setProgress(int value) { 192 if (mHasStarted) { 193 mProgress.setProgress(value); 194 onProgressChanged(); 195 } else { 196 mProgressVal = value; 197 } 198 } 199 setSecondaryProgress(int secondaryProgress)200 public void setSecondaryProgress(int secondaryProgress) { 201 if (mProgress != null) { 202 mProgress.setSecondaryProgress(secondaryProgress); 203 onProgressChanged(); 204 } else { 205 mSecondaryProgressVal = secondaryProgress; 206 } 207 } 208 getProgress()209 public int getProgress() { 210 if (mProgress != null) { 211 return mProgress.getProgress(); 212 } 213 return mProgressVal; 214 } 215 getSecondaryProgress()216 public int getSecondaryProgress() { 217 if (mProgress != null) { 218 return mProgress.getSecondaryProgress(); 219 } 220 return mSecondaryProgressVal; 221 } 222 getMax()223 public int getMax() { 224 if (mProgress != null) { 225 return mProgress.getMax(); 226 } 227 return mMax; 228 } 229 setMax(int max)230 public void setMax(int max) { 231 if (mProgress != null) { 232 mProgress.setMax(max); 233 onProgressChanged(); 234 } else { 235 mMax = max; 236 } 237 } 238 incrementProgressBy(int diff)239 public void incrementProgressBy(int diff) { 240 if (mProgress != null) { 241 mProgress.incrementProgressBy(diff); 242 onProgressChanged(); 243 } else { 244 mIncrementBy += diff; 245 } 246 } 247 incrementSecondaryProgressBy(int diff)248 public void incrementSecondaryProgressBy(int diff) { 249 if (mProgress != null) { 250 mProgress.incrementSecondaryProgressBy(diff); 251 onProgressChanged(); 252 } else { 253 mIncrementSecondaryBy += diff; 254 } 255 } 256 setProgressDrawable(Drawable d)257 public void setProgressDrawable(Drawable d) { 258 if (mProgress != null) { 259 mProgress.setProgressDrawable(d); 260 } else { 261 mProgressDrawable = d; 262 } 263 } 264 setIndeterminateDrawable(Drawable d)265 public void setIndeterminateDrawable(Drawable d) { 266 if (mProgress != null) { 267 mProgress.setIndeterminateDrawable(d); 268 } else { 269 mIndeterminateDrawable = d; 270 } 271 } 272 setIndeterminate(boolean indeterminate)273 public void setIndeterminate(boolean indeterminate) { 274 if (mProgress != null) { 275 mProgress.setIndeterminate(indeterminate); 276 } else { 277 mIndeterminate = indeterminate; 278 } 279 } 280 isIndeterminate()281 public boolean isIndeterminate() { 282 if (mProgress != null) { 283 return mProgress.isIndeterminate(); 284 } 285 return mIndeterminate; 286 } 287 288 @Override setMessage(CharSequence message)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 setProgressStyle(int style)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 */ setProgressNumberFormat(String format)312 public void setProgressNumberFormat(String format) { 313 mProgressNumberFormat = format; 314 } 315 onProgressChanged()316 private void onProgressChanged() { 317 if (mProgressStyle == STYLE_HORIZONTAL) { 318 mViewUpdateHandler.sendEmptyMessage(0); 319 } 320 } 321 } 322