blob: d421173c5080abc46e8d0167a469f16bbd234c7c [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
19import android.content.Context;
20import android.graphics.drawable.Drawable;
21import android.os.Bundle;
22import android.os.Handler;
23import android.os.Message;
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -070024import android.text.Spannable;
25import android.text.SpannableString;
26import android.text.style.StyleSpan;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import 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
Adam Powell6af97e12010-11-11 21:11:53 -080044 /** Creates a ProgressDialog with a circular, spinning progress
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 * 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;
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -070058 private String mProgressNumberFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 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) {
Adam Powell548f76f2010-10-19 19:01:55 -070076 super(context);
Dianne Hackborn43894342011-01-12 11:17:17 -080077 initFormats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 }
79
80 public ProgressDialog(Context context, int theme) {
81 super(context, theme);
Dianne Hackborn43894342011-01-12 11:17:17 -080082 initFormats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 }
84
Dianne Hackborn43894342011-01-12 11:17:17 -080085 private void initFormats() {
86 mProgressNumberFormat = "%1d/%2d";
87 mProgressPercentFormat = NumberFormat.getPercentInstance();
88 mProgressPercentFormat.setMaximumFractionDigits(0);
89 }
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 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();
Dianne Hackborn43894342011-01-12 11:17:17 -0800135 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 }
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);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 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
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700318 /**
Dianne Hackborn43894342011-01-12 11:17:17 -0800319 * Change the format of the small text showing current and maximum units
320 * of progress. The default is "%1d/%2d".
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700321 * Should not be called during the number is progressing.
Dianne Hackborn43894342011-01-12 11:17:17 -0800322 * @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.
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700325 */
326 public void setProgressNumberFormat(String format) {
327 mProgressNumberFormat = format;
Dianne Hackborn43894342011-01-12 11:17:17 -0800328 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();
Daisuke Miyakawaeb3e3e32009-04-02 10:44:31 -0700342 }
343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 private void onProgressChanged() {
345 if (mProgressStyle == STYLE_HORIZONTAL) {
Dianne Hackborn43894342011-01-12 11:17:17 -0800346 if (!mViewUpdateHandler.hasMessages(0)) {
347 mViewUpdateHandler.sendEmptyMessage(0);
348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 }
350 }
351}