blob: 3193eb89ac80934c4ffe3a1b4790934b9a1cdba4 [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
import com.android.internal.R;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.NumberFormat;
/**
* A dialog showing a progress indicator and an optional text message or view.
* Only a text message or a view can be used at the same time.
*
* <p>The dialog can be made cancelable on back key press.</p>
*
* <p>The progress range is 0 to {@link #getMax() max}.</p>
*
* @deprecated <code>ProgressDialog</code> is a modal dialog, which prevents the
* user from interacting with the app. Instead of using this class, you should
* use a progress indicator like {@link android.widget.ProgressBar}, which can
* be embedded in your app's UI. Alternatively, you can use a
* <a href="/guide/topics/ui/notifiers/notifications.html">notification</a>
* to inform the user of the task's progress.
*/
@Deprecated
public class ProgressDialog extends AlertDialog {
/**
* Creates a ProgressDialog with a circular, spinning progress
* bar. This is the default.
*/
public static final int STYLE_SPINNER = 0;
/**
* Creates a ProgressDialog with a horizontal progress bar.
*/
public static final int STYLE_HORIZONTAL = 1;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private ProgressBar mProgress;
@UnsupportedAppUsage
private TextView mMessageView;
private int mProgressStyle = STYLE_SPINNER;
@UnsupportedAppUsage
private TextView mProgressNumber;
private String mProgressNumberFormat;
private TextView mProgressPercent;
private NumberFormat mProgressPercentFormat;
private int mMax;
private int mProgressVal;
private int mSecondaryProgressVal;
private int mIncrementBy;
private int mIncrementSecondaryBy;
private Drawable mProgressDrawable;
private Drawable mIndeterminateDrawable;
private CharSequence mMessage;
private boolean mIndeterminate;
private boolean mHasStarted;
private Handler mViewUpdateHandler;
/**
* Creates a Progress dialog.
*
* @param context the parent context
*/
public ProgressDialog(Context context) {
super(context);
initFormats();
}
/**
* Creates a Progress dialog.
*
* @param context the parent context
* @param theme the resource ID of the theme against which to inflate
* this dialog, or {@code 0} to use the parent
* {@code context}'s default alert dialog theme
*/
public ProgressDialog(Context context, int theme) {
super(context, theme);
initFormats();
}
private void initFormats() {
mProgressNumberFormat = "%1d/%2d";
mProgressPercentFormat = NumberFormat.getPercentInstance();
mProgressPercentFormat.setMaximumFractionDigits(0);
}
/**
* Creates and shows a ProgressDialog.
*
* @param context the parent context
* @param title the title text for the dialog's window
* @param message the text to be displayed in the dialog
* @return the ProgressDialog
*/
public static ProgressDialog show(Context context, CharSequence title,
CharSequence message) {
return show(context, title, message, false);
}
/**
* Creates and shows a ProgressDialog.
*
* @param context the parent context
* @param title the title text for the dialog's window
* @param message the text to be displayed in the dialog
* @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
* indeterminate}, false otherwise
* @return the ProgressDialog
*/
public static ProgressDialog show(Context context, CharSequence title,
CharSequence message, boolean indeterminate) {
return show(context, title, message, indeterminate, false, null);
}
/**
* Creates and shows a ProgressDialog.
*
* @param context the parent context
* @param title the title text for the dialog's window
* @param message the text to be displayed in the dialog
* @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
* indeterminate}, false otherwise
* @param cancelable true if the dialog is {@link #setCancelable(boolean) cancelable},
* false otherwise
* @return the ProgressDialog
*/
public static ProgressDialog show(Context context, CharSequence title,
CharSequence message, boolean indeterminate, boolean cancelable) {
return show(context, title, message, indeterminate, cancelable, null);
}
/**
* Creates and shows a ProgressDialog.
*
* @param context the parent context
* @param title the title text for the dialog's window
* @param message the text to be displayed in the dialog
* @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
* indeterminate}, false otherwise
* @param cancelable true if the dialog is {@link #setCancelable(boolean) cancelable},
* false otherwise
* @param cancelListener the {@link #setOnCancelListener(OnCancelListener) listener}
* to be invoked when the dialog is canceled
* @return the ProgressDialog
*/
public static ProgressDialog show(Context context, CharSequence title,
CharSequence message, boolean indeterminate,
boolean cancelable, OnCancelListener cancelListener) {
ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setIndeterminate(indeterminate);
dialog.setCancelable(cancelable);
dialog.setOnCancelListener(cancelListener);
dialog.show();
return dialog;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(mContext);
TypedArray a = mContext.obtainStyledAttributes(null,
com.android.internal.R.styleable.AlertDialog,
com.android.internal.R.attr.alertDialogStyle, 0);
if (mProgressStyle == STYLE_HORIZONTAL) {
/* Use a separate handler to update the text views as they
* must be updated on the same thread that created them.
*/
mViewUpdateHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
/* Update the number and percent */
int progress = mProgress.getProgress();
int max = mProgress.getMax();
if (mProgressNumberFormat != null) {
String format = mProgressNumberFormat;
mProgressNumber.setText(String.format(format, progress, max));
} else {
mProgressNumber.setText("");
}
if (mProgressPercentFormat != null) {
double percent = (double) progress / (double) max;
SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mProgressPercent.setText(tmp);
} else {
mProgressPercent.setText("");
}
}
};
View view = inflater.inflate(a.getResourceId(
com.android.internal.R.styleable.AlertDialog_horizontalProgressLayout,
R.layout.alert_dialog_progress), null);
mProgress = (ProgressBar) view.findViewById(R.id.progress);
mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
setView(view);
} else {
View view = inflater.inflate(a.getResourceId(
com.android.internal.R.styleable.AlertDialog_progressLayout,
R.layout.progress_dialog), null);
mProgress = (ProgressBar) view.findViewById(R.id.progress);
mMessageView = (TextView) view.findViewById(R.id.message);
setView(view);
}
a.recycle();
if (mMax > 0) {
setMax(mMax);
}
if (mProgressVal > 0) {
setProgress(mProgressVal);
}
if (mSecondaryProgressVal > 0) {
setSecondaryProgress(mSecondaryProgressVal);
}
if (mIncrementBy > 0) {
incrementProgressBy(mIncrementBy);
}
if (mIncrementSecondaryBy > 0) {
incrementSecondaryProgressBy(mIncrementSecondaryBy);
}
if (mProgressDrawable != null) {
setProgressDrawable(mProgressDrawable);
}
if (mIndeterminateDrawable != null) {
setIndeterminateDrawable(mIndeterminateDrawable);
}
if (mMessage != null) {
setMessage(mMessage);
}
setIndeterminate(mIndeterminate);
onProgressChanged();
super.onCreate(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
mHasStarted = true;
}
@Override
protected void onStop() {
super.onStop();
mHasStarted = false;
}
/**
* Sets the current progress.
*
* @param value the current progress, a value between 0 and {@link #getMax()}
*
* @see ProgressBar#setProgress(int)
*/
public void setProgress(int value) {
if (mHasStarted) {
mProgress.setProgress(value);
onProgressChanged();
} else {
mProgressVal = value;
}
}
/**
* Sets the secondary progress.
*
* @param secondaryProgress the current secondary progress, a value between 0 and
* {@link #getMax()}
*
* @see ProgressBar#setSecondaryProgress(int)
*/
public void setSecondaryProgress(int secondaryProgress) {
if (mProgress != null) {
mProgress.setSecondaryProgress(secondaryProgress);
onProgressChanged();
} else {
mSecondaryProgressVal = secondaryProgress;
}
}
/**
* Gets the current progress.
*
* @return the current progress, a value between 0 and {@link #getMax()}
*/
public int getProgress() {
if (mProgress != null) {
return mProgress.getProgress();
}
return mProgressVal;
}
/**
* Gets the current secondary progress.
*
* @return the current secondary progress, a value between 0 and {@link #getMax()}
*/
public int getSecondaryProgress() {
if (mProgress != null) {
return mProgress.getSecondaryProgress();
}
return mSecondaryProgressVal;
}
/**
* Gets the maximum allowed progress value. The default value is 100.
*
* @return the maximum value
*/
public int getMax() {
if (mProgress != null) {
return mProgress.getMax();
}
return mMax;
}
/**
* Sets the maximum allowed progress value.
*/
public void setMax(int max) {
if (mProgress != null) {
mProgress.setMax(max);
onProgressChanged();
} else {
mMax = max;
}
}
/**
* Increments the current progress value.
*
* @param diff the amount by which the current progress will be incremented,
* up to {@link #getMax()}
*/
public void incrementProgressBy(int diff) {
if (mProgress != null) {
mProgress.incrementProgressBy(diff);
onProgressChanged();
} else {
mIncrementBy += diff;
}
}
/**
* Increments the current secondary progress value.
*
* @param diff the amount by which the current secondary progress will be incremented,
* up to {@link #getMax()}
*/
public void incrementSecondaryProgressBy(int diff) {
if (mProgress != null) {
mProgress.incrementSecondaryProgressBy(diff);
onProgressChanged();
} else {
mIncrementSecondaryBy += diff;
}
}
/**
* Sets the drawable to be used to display the progress value.
*
* @param d the drawable to be used
*
* @see ProgressBar#setProgressDrawable(Drawable)
*/
public void setProgressDrawable(Drawable d) {
if (mProgress != null) {
mProgress.setProgressDrawable(d);
} else {
mProgressDrawable = d;
}
}
/**
* Sets the drawable to be used to display the indeterminate progress value.
*
* @param d the drawable to be used
*
* @see ProgressBar#setProgressDrawable(Drawable)
* @see #setIndeterminate(boolean)
*/
public void setIndeterminateDrawable(Drawable d) {
if (mProgress != null) {
mProgress.setIndeterminateDrawable(d);
} else {
mIndeterminateDrawable = d;
}
}
/**
* Change the indeterminate mode for this ProgressDialog. In indeterminate
* mode, the progress is ignored and the dialog shows an infinite
* animation instead.
*
* <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
* is always indeterminate and will ignore this setting.</p>
*
* @param indeterminate true to enable indeterminate mode, false otherwise
*
* @see #setProgressStyle(int)
*/
public void setIndeterminate(boolean indeterminate) {
if (mProgress != null) {
mProgress.setIndeterminate(indeterminate);
} else {
mIndeterminate = indeterminate;
}
}
/**
* Whether this ProgressDialog is in indeterminate mode.
*
* @return true if the dialog is in indeterminate mode, false otherwise
*/
public boolean isIndeterminate() {
if (mProgress != null) {
return mProgress.isIndeterminate();
}
return mIndeterminate;
}
@Override
public void setMessage(CharSequence message) {
if (mProgress != null) {
if (mProgressStyle == STYLE_HORIZONTAL) {
super.setMessage(message);
} else {
mMessageView.setText(message);
}
} else {
mMessage = message;
}
}
/**
* Sets the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
* {@link #STYLE_HORIZONTAL}. The default is {@link #STYLE_SPINNER}.
*
* <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
* is always indeterminate and will ignore the {@link #setIndeterminate(boolean)
* indeterminate} setting.</p>
*
* @param style the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
* {@link #STYLE_HORIZONTAL}
*/
public void setProgressStyle(int style) {
mProgressStyle = style;
}
/**
* Change the format of the small text showing current and maximum units
* of progress. The default is "%1d/%2d".
* Should not be called during the number is progressing.
* @param format A string passed to {@link String#format String.format()};
* use "%1d" for the current number and "%2d" for the maximum. If null,
* nothing will be shown.
*/
public void setProgressNumberFormat(String format) {
mProgressNumberFormat = format;
onProgressChanged();
}
/**
* Change the format of the small text showing the percentage of progress.
* The default is
* {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
* Should not be called during the number is progressing.
* @param format An instance of a {@link NumberFormat} to generate the
* percentage text. If null, nothing will be shown.
*/
public void setProgressPercentFormat(NumberFormat format) {
mProgressPercentFormat = format;
onProgressChanged();
}
private void onProgressChanged() {
if (mProgressStyle == STYLE_HORIZONTAL) {
if (mViewUpdateHandler != null && !mViewUpdateHandler.hasMessages(0)) {
mViewUpdateHandler.sendEmptyMessage(0);
}
}
}
}