blob: 7f1f3850a3978192575b73688d08052627ac88f3 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Adam Powellba3c3772011-09-09 16:22:34 -070019import com.android.internal.R;
20
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
Adam Powellba3c3772011-09-09 16:22:34 -070022import android.content.res.TypedArray;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.graphics.drawable.Drawable;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.Message;
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -070027import android.text.Spannable;
28import android.text.SpannableString;
29import android.text.style.StyleSpan;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.view.LayoutInflater;
31import android.view.View;
32import android.widget.ProgressBar;
33import android.widget.TextView;
34
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import java.text.NumberFormat;
36
37/**
38 * <p>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.</p>
40 * <p>The dialog can be made cancelable on back key press.</p>
41 * <p>The progress range is 0..10000.</p>
42 */
43public class ProgressDialog extends AlertDialog {
44
Adam Powell6af97e12010-11-11 21:11:53 -080045 /** Creates a ProgressDialog with a circular, spinning progress
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 * bar. This is the default.
47 */
48 public static final int STYLE_SPINNER = 0;
49
50 /** Creates a ProgressDialog with a horizontal progress bar.
51 */
52 public static final int STYLE_HORIZONTAL = 1;
53
54 private ProgressBar mProgress;
55 private TextView mMessageView;
56
57 private int mProgressStyle = STYLE_SPINNER;
58 private TextView mProgressNumber;
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -070059 private String mProgressNumberFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 private TextView mProgressPercent;
61 private NumberFormat mProgressPercentFormat;
62
63 private int mMax;
64 private int mProgressVal;
65 private int mSecondaryProgressVal;
66 private int mIncrementBy;
67 private int mIncrementSecondaryBy;
68 private Drawable mProgressDrawable;
69 private Drawable mIndeterminateDrawable;
70 private CharSequence mMessage;
71 private boolean mIndeterminate;
72
73 private boolean mHasStarted;
74 private Handler mViewUpdateHandler;
75
76 public ProgressDialog(Context context) {
Adam Powell548f76f2010-10-19 19:01:55 -070077 super(context);
Dianne Hackborn43894342011-01-12 11:17:17 -080078 initFormats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 }
80
81 public ProgressDialog(Context context, int theme) {
82 super(context, theme);
Dianne Hackborn43894342011-01-12 11:17:17 -080083 initFormats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 }
85
Dianne Hackborn43894342011-01-12 11:17:17 -080086 private void initFormats() {
87 mProgressNumberFormat = "%1d/%2d";
88 mProgressPercentFormat = NumberFormat.getPercentInstance();
89 mProgressPercentFormat.setMaximumFractionDigits(0);
90 }
91
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 public static ProgressDialog show(Context context, CharSequence title,
93 CharSequence message) {
94 return show(context, title, message, false);
95 }
96
97 public static ProgressDialog show(Context context, CharSequence title,
98 CharSequence message, boolean indeterminate) {
99 return show(context, title, message, indeterminate, false, null);
100 }
101
102 public static ProgressDialog show(Context context, CharSequence title,
103 CharSequence message, boolean indeterminate, boolean cancelable) {
104 return show(context, title, message, indeterminate, cancelable, null);
105 }
106
107 public static ProgressDialog show(Context context, CharSequence title,
108 CharSequence message, boolean indeterminate,
109 boolean cancelable, OnCancelListener cancelListener) {
110 ProgressDialog dialog = new ProgressDialog(context);
111 dialog.setTitle(title);
112 dialog.setMessage(message);
113 dialog.setIndeterminate(indeterminate);
114 dialog.setCancelable(cancelable);
115 dialog.setOnCancelListener(cancelListener);
116 dialog.show();
117 return dialog;
118 }
119
120 @Override
121 protected void onCreate(Bundle savedInstanceState) {
122 LayoutInflater inflater = LayoutInflater.from(mContext);
Adam Powellba3c3772011-09-09 16:22:34 -0700123 TypedArray a = mContext.obtainStyledAttributes(null,
124 com.android.internal.R.styleable.AlertDialog,
125 com.android.internal.R.attr.alertDialogStyle, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 if (mProgressStyle == STYLE_HORIZONTAL) {
127
128 /* Use a separate handler to update the text views as they
129 * must be updated on the same thread that created them.
130 */
131 mViewUpdateHandler = new Handler() {
132 @Override
133 public void handleMessage(Message msg) {
134 super.handleMessage(msg);
135
136 /* Update the number and percent */
137 int progress = mProgress.getProgress();
138 int max = mProgress.getMax();
Dianne Hackborn43894342011-01-12 11:17:17 -0800139 if (mProgressNumberFormat != null) {
140 String format = mProgressNumberFormat;
141 mProgressNumber.setText(String.format(format, progress, max));
142 } else {
143 mProgressNumber.setText("");
144 }
145 if (mProgressPercentFormat != null) {
146 double percent = (double) progress / (double) max;
147 SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
148 tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
149 0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
150 mProgressPercent.setText(tmp);
151 } else {
152 mProgressPercent.setText("");
153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 }
155 };
Adam Powellba3c3772011-09-09 16:22:34 -0700156 View view = inflater.inflate(a.getResourceId(
157 com.android.internal.R.styleable.AlertDialog_horizontalProgressLayout,
158 R.layout.alert_dialog_progress), null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 mProgress = (ProgressBar) view.findViewById(R.id.progress);
160 mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
161 mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 setView(view);
163 } else {
Adam Powellba3c3772011-09-09 16:22:34 -0700164 View view = inflater.inflate(a.getResourceId(
165 com.android.internal.R.styleable.AlertDialog_progressLayout,
166 R.layout.progress_dialog), null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 mProgress = (ProgressBar) view.findViewById(R.id.progress);
168 mMessageView = (TextView) view.findViewById(R.id.message);
169 setView(view);
170 }
Adam Powellba3c3772011-09-09 16:22:34 -0700171 a.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 if (mMax > 0) {
173 setMax(mMax);
174 }
175 if (mProgressVal > 0) {
176 setProgress(mProgressVal);
177 }
178 if (mSecondaryProgressVal > 0) {
179 setSecondaryProgress(mSecondaryProgressVal);
180 }
181 if (mIncrementBy > 0) {
182 incrementProgressBy(mIncrementBy);
183 }
184 if (mIncrementSecondaryBy > 0) {
185 incrementSecondaryProgressBy(mIncrementSecondaryBy);
186 }
187 if (mProgressDrawable != null) {
188 setProgressDrawable(mProgressDrawable);
189 }
190 if (mIndeterminateDrawable != null) {
191 setIndeterminateDrawable(mIndeterminateDrawable);
192 }
193 if (mMessage != null) {
194 setMessage(mMessage);
195 }
196 setIndeterminate(mIndeterminate);
197 onProgressChanged();
198 super.onCreate(savedInstanceState);
199 }
200
201 @Override
202 public void onStart() {
203 super.onStart();
204 mHasStarted = true;
205 }
206
207 @Override
208 protected void onStop() {
209 super.onStop();
210 mHasStarted = false;
211 }
212
213 public void setProgress(int value) {
214 if (mHasStarted) {
215 mProgress.setProgress(value);
216 onProgressChanged();
217 } else {
218 mProgressVal = value;
219 }
220 }
221
222 public void setSecondaryProgress(int secondaryProgress) {
223 if (mProgress != null) {
224 mProgress.setSecondaryProgress(secondaryProgress);
225 onProgressChanged();
226 } else {
227 mSecondaryProgressVal = secondaryProgress;
228 }
229 }
230
231 public int getProgress() {
232 if (mProgress != null) {
233 return mProgress.getProgress();
234 }
235 return mProgressVal;
236 }
237
238 public int getSecondaryProgress() {
239 if (mProgress != null) {
240 return mProgress.getSecondaryProgress();
241 }
242 return mSecondaryProgressVal;
243 }
244
245 public int getMax() {
246 if (mProgress != null) {
247 return mProgress.getMax();
248 }
249 return mMax;
250 }
251
252 public void setMax(int max) {
253 if (mProgress != null) {
254 mProgress.setMax(max);
255 onProgressChanged();
256 } else {
257 mMax = max;
258 }
259 }
260
261 public void incrementProgressBy(int diff) {
262 if (mProgress != null) {
263 mProgress.incrementProgressBy(diff);
264 onProgressChanged();
265 } else {
266 mIncrementBy += diff;
267 }
268 }
269
270 public void incrementSecondaryProgressBy(int diff) {
271 if (mProgress != null) {
272 mProgress.incrementSecondaryProgressBy(diff);
273 onProgressChanged();
274 } else {
275 mIncrementSecondaryBy += diff;
276 }
277 }
278
279 public void setProgressDrawable(Drawable d) {
280 if (mProgress != null) {
281 mProgress.setProgressDrawable(d);
282 } else {
283 mProgressDrawable = d;
284 }
285 }
286
287 public void setIndeterminateDrawable(Drawable d) {
288 if (mProgress != null) {
289 mProgress.setIndeterminateDrawable(d);
290 } else {
291 mIndeterminateDrawable = d;
292 }
293 }
294
295 public void setIndeterminate(boolean indeterminate) {
296 if (mProgress != null) {
297 mProgress.setIndeterminate(indeterminate);
298 } else {
299 mIndeterminate = indeterminate;
300 }
301 }
302
303 public boolean isIndeterminate() {
304 if (mProgress != null) {
305 return mProgress.isIndeterminate();
306 }
307 return mIndeterminate;
308 }
309
310 @Override
311 public void setMessage(CharSequence message) {
312 if (mProgress != null) {
313 if (mProgressStyle == STYLE_HORIZONTAL) {
314 super.setMessage(message);
315 } else {
316 mMessageView.setText(message);
317 }
318 } else {
319 mMessage = message;
320 }
321 }
322
323 public void setProgressStyle(int style) {
324 mProgressStyle = style;
325 }
326
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700327 /**
Dianne Hackborn43894342011-01-12 11:17:17 -0800328 * Change the format of the small text showing current and maximum units
329 * of progress. The default is "%1d/%2d".
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700330 * Should not be called during the number is progressing.
Dianne Hackborn43894342011-01-12 11:17:17 -0800331 * @param format A string passed to {@link String#format String.format()};
332 * use "%1d" for the current number and "%2d" for the maximum. If null,
333 * nothing will be shown.
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700334 */
335 public void setProgressNumberFormat(String format) {
336 mProgressNumberFormat = format;
Dianne Hackborn43894342011-01-12 11:17:17 -0800337 onProgressChanged();
338 }
339
340 /**
341 * Change the format of the small text showing the percentage of progress.
342 * The default is
343 * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
344 * Should not be called during the number is progressing.
345 * @param format An instance of a {@link NumberFormat} to generate the
346 * percentage text. If null, nothing will be shown.
347 */
348 public void setProgressPercentFormat(NumberFormat format) {
349 mProgressPercentFormat = format;
350 onProgressChanged();
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700351 }
352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 private void onProgressChanged() {
354 if (mProgressStyle == STYLE_HORIZONTAL) {
Adam Powell5d4faa92011-08-23 16:52:35 -0700355 if (mViewUpdateHandler != null && !mViewUpdateHandler.hasMessages(0)) {
Dianne Hackborn43894342011-01-12 11:17:17 -0800356 mViewUpdateHandler.sendEmptyMessage(0);
357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 }
359 }
360}