summaryrefslogtreecommitdiffstats
path: root/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java
diff options
context:
space:
mode:
Diffstat (limited to 'actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java')
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java1193
1 files changed, 0 insertions, 1193 deletions
diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java
deleted file mode 100644
index 1c02d4aca..000000000
--- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java
+++ /dev/null
@@ -1,1193 +0,0 @@
-/*
- * Copyright (C) 2006 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 com.actionbarsherlock.internal.widget;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Shader;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ClipDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RoundRectShape;
-import android.graphics.drawable.shapes.Shape;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.Transformation;
-import android.widget.RemoteViews.RemoteView;
-
-
-/**
- * <p>
- * Visual indicator of progress in some operation. Displays a bar to the user
- * representing how far the operation has progressed; the application can
- * change the amount of progress (modifying the length of the bar) as it moves
- * forward. There is also a secondary progress displayable on a progress bar
- * which is useful for displaying intermediate progress, such as the buffer
- * level during a streaming playback progress bar.
- * </p>
- *
- * <p>
- * A progress bar can also be made indeterminate. In indeterminate mode, the
- * progress bar shows a cyclic animation without an indication of progress. This mode is used by
- * applications when the length of the task is unknown. The indeterminate progress bar can be either
- * a spinning wheel or a horizontal bar.
- * </p>
- *
- * <p>The following code example shows how a progress bar can be used from
- * a worker thread to update the user interface to notify the user of progress:
- * </p>
- *
- * <pre>
- * public class MyActivity extends Activity {
- * private static final int PROGRESS = 0x1;
- *
- * private ProgressBar mProgress;
- * private int mProgressStatus = 0;
- *
- * private Handler mHandler = new Handler();
- *
- * protected void onCreate(Bundle icicle) {
- * super.onCreate(icicle);
- *
- * setContentView(R.layout.progressbar_activity);
- *
- * mProgress = (ProgressBar) findViewById(R.id.progress_bar);
- *
- * // Start lengthy operation in a background thread
- * new Thread(new Runnable() {
- * public void run() {
- * while (mProgressStatus &lt; 100) {
- * mProgressStatus = doWork();
- *
- * // Update the progress bar
- * mHandler.post(new Runnable() {
- * public void run() {
- * mProgress.setProgress(mProgressStatus);
- * }
- * });
- * }
- * }
- * }).start();
- * }
- * }</pre>
- *
- * <p>To add a progress bar to a layout file, you can use the {@code &lt;ProgressBar&gt;} element.
- * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a
- * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal
- * Widget.ProgressBar.Horizontal} style, like so:</p>
- *
- * <pre>
- * &lt;ProgressBar
- * style="@android:style/Widget.ProgressBar.Horizontal"
- * ... /&gt;</pre>
- *
- * <p>If you will use the progress bar to show real progress, you must use the horizontal bar. You
- * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or
- * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If
- * necessary, you can adjust the maximum value (the value for a full bar) using the {@link
- * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed
- * below.</p>
- *
- * <p>Another common style to apply to the progress bar is {@link
- * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller
- * version of the spinning wheel&mdash;useful when waiting for content to load.
- * For example, you can insert this kind of progress bar into your default layout for
- * a view that will be populated by some content fetched from the Internet&mdash;the spinning wheel
- * appears immediately and when your application receives the content, it replaces the progress bar
- * with the loaded content. For example:</p>
- *
- * <pre>
- * &lt;LinearLayout
- * android:orientation="horizontal"
- * ... &gt;
- * &lt;ProgressBar
- * android:layout_width="wrap_content"
- * android:layout_height="wrap_content"
- * style="@android:style/Widget.ProgressBar.Small"
- * android:layout_marginRight="5dp" /&gt;
- * &lt;TextView
- * android:layout_width="wrap_content"
- * android:layout_height="wrap_content"
- * android:text="@string/loading" /&gt;
- * &lt;/LinearLayout&gt;</pre>
- *
- * <p>Other progress bar styles provided by the system include:</p>
- * <ul>
- * <li>{@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}</li>
- * <li>{@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}</li>
- * <li>{@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}</li>
- * <li>{@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}</li>
- * <li>{@link android.R.style#Widget_ProgressBar_Small_Inverse
- * Widget.ProgressBar.Small.Inverse}</li>
- * <li>{@link android.R.style#Widget_ProgressBar_Large_Inverse
- * Widget.ProgressBar.Large.Inverse}</li>
- * </ul>
- * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary
- * if your application uses a light colored theme (a white background).</p>
- *
- * <p><strong>XML attributes</b></strong>
- * <p>
- * See {@link android.R.styleable#ProgressBar ProgressBar Attributes},
- * {@link android.R.styleable#View View Attributes}
- * </p>
- *
- * @attr ref android.R.styleable#ProgressBar_animationResolution
- * @attr ref android.R.styleable#ProgressBar_indeterminate
- * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior
- * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable
- * @attr ref android.R.styleable#ProgressBar_indeterminateDuration
- * @attr ref android.R.styleable#ProgressBar_indeterminateOnly
- * @attr ref android.R.styleable#ProgressBar_interpolator
- * @attr ref android.R.styleable#ProgressBar_max
- * @attr ref android.R.styleable#ProgressBar_maxHeight
- * @attr ref android.R.styleable#ProgressBar_maxWidth
- * @attr ref android.R.styleable#ProgressBar_minHeight
- * @attr ref android.R.styleable#ProgressBar_minWidth
- * @attr ref android.R.styleable#ProgressBar_progress
- * @attr ref android.R.styleable#ProgressBar_progressDrawable
- * @attr ref android.R.styleable#ProgressBar_secondaryProgress
- */
-@RemoteView
-public class IcsProgressBar extends View {
- private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
- private static final int MAX_LEVEL = 10000;
- private static final int ANIMATION_RESOLUTION = 200;
- private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
-
- private static final int[] ProgressBar = new int[] {
- android.R.attr.maxWidth,
- android.R.attr.maxHeight,
- android.R.attr.max,
- android.R.attr.progress,
- android.R.attr.secondaryProgress,
- android.R.attr.indeterminate,
- android.R.attr.indeterminateOnly,
- android.R.attr.indeterminateDrawable,
- android.R.attr.progressDrawable,
- android.R.attr.indeterminateDuration,
- android.R.attr.indeterminateBehavior,
- android.R.attr.minWidth,
- android.R.attr.minHeight,
- android.R.attr.interpolator,
- android.R.attr.animationResolution,
- };
- private static final int ProgressBar_maxWidth = 0;
- private static final int ProgressBar_maxHeight = 1;
- private static final int ProgressBar_max = 2;
- private static final int ProgressBar_progress = 3;
- private static final int ProgressBar_secondaryProgress = 4;
- private static final int ProgressBar_indeterminate = 5;
- private static final int ProgressBar_indeterminateOnly = 6;
- private static final int ProgressBar_indeterminateDrawable = 7;
- private static final int ProgressBar_progressDrawable = 8;
- private static final int ProgressBar_indeterminateDuration = 9;
- private static final int ProgressBar_indeterminateBehavior = 10;
- private static final int ProgressBar_minWidth = 11;
- private static final int ProgressBar_minHeight = 12;
- private static final int ProgressBar_interpolator = 13;
- private static final int ProgressBar_animationResolution = 14;
-
- int mMinWidth;
- int mMaxWidth;
- int mMinHeight;
- int mMaxHeight;
-
- private int mProgress;
- private int mSecondaryProgress;
- private int mMax;
-
- private int mBehavior;
- private int mDuration;
- private boolean mIndeterminate;
- private boolean mOnlyIndeterminate;
- private Transformation mTransformation;
- private AlphaAnimation mAnimation;
- private Drawable mIndeterminateDrawable;
- private int mIndeterminateRealLeft;
- private int mIndeterminateRealTop;
- private Drawable mProgressDrawable;
- private Drawable mCurrentDrawable;
- Bitmap mSampleTile;
- private boolean mNoInvalidate;
- private Interpolator mInterpolator;
- private RefreshProgressRunnable mRefreshProgressRunnable;
- private long mUiThreadId;
- private boolean mShouldStartAnimationDrawable;
- private long mLastDrawTime;
-
- private boolean mInDrawing;
-
- private int mAnimationResolution;
-
- private AccessibilityManager mAccessibilityManager;
- private AccessibilityEventSender mAccessibilityEventSender;
-
- /**
- * Create a new progress bar with range 0...100 and initial progress of 0.
- * @param context the application environment
- */
- public IcsProgressBar(Context context) {
- this(context, null);
- }
-
- public IcsProgressBar(Context context, AttributeSet attrs) {
- this(context, attrs, android.R.attr.progressBarStyle);
- }
-
- public IcsProgressBar(Context context, AttributeSet attrs, int defStyle) {
- this(context, attrs, defStyle, 0);
- }
-
- /**
- * @hide
- */
- public IcsProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) {
- super(context, attrs, defStyle);
- mUiThreadId = Thread.currentThread().getId();
- initProgressBar();
-
- TypedArray a =
- context.obtainStyledAttributes(attrs, /*R.styleable.*/ProgressBar, defStyle, styleRes);
-
- mNoInvalidate = true;
-
- Drawable drawable = a.getDrawable(/*R.styleable.*/ProgressBar_progressDrawable);
- if (drawable != null) {
- drawable = tileify(drawable, false);
- // Calling this method can set mMaxHeight, make sure the corresponding
- // XML attribute for mMaxHeight is read after calling this method
- setProgressDrawable(drawable);
- }
-
-
- mDuration = a.getInt(/*R.styleable.*/ProgressBar_indeterminateDuration, mDuration);
-
- mMinWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minWidth, mMinWidth);
- mMaxWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxWidth, mMaxWidth);
- mMinHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minHeight, mMinHeight);
- mMaxHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxHeight, mMaxHeight);
-
- mBehavior = a.getInt(/*R.styleable.*/ProgressBar_indeterminateBehavior, mBehavior);
-
- final int resID = a.getResourceId(
- /*com.android.internal.R.styleable.*/ProgressBar_interpolator,
- android.R.anim.linear_interpolator); // default to linear interpolator
- if (resID > 0) {
- setInterpolator(context, resID);
- }
-
- setMax(a.getInt(/*R.styleable.*/ProgressBar_max, mMax));
-
- setProgress(a.getInt(/*R.styleable.*/ProgressBar_progress, mProgress));
-
- setSecondaryProgress(
- a.getInt(/*R.styleable.*/ProgressBar_secondaryProgress, mSecondaryProgress));
-
- drawable = a.getDrawable(/*R.styleable.*/ProgressBar_indeterminateDrawable);
- if (drawable != null) {
- drawable = tileifyIndeterminate(drawable);
- setIndeterminateDrawable(drawable);
- }
-
- mOnlyIndeterminate = a.getBoolean(
- /*R.styleable.*/ProgressBar_indeterminateOnly, mOnlyIndeterminate);
-
- mNoInvalidate = false;
-
- setIndeterminate(mOnlyIndeterminate || a.getBoolean(
- /*R.styleable.*/ProgressBar_indeterminate, mIndeterminate));
-
- mAnimationResolution = a.getInteger(/*R.styleable.*/ProgressBar_animationResolution,
- ANIMATION_RESOLUTION);
-
- a.recycle();
-
- mAccessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE);
- }
-
- /**
- * Converts a drawable to a tiled version of itself. It will recursively
- * traverse layer and state list drawables.
- */
- private Drawable tileify(Drawable drawable, boolean clip) {
-
- if (drawable instanceof LayerDrawable) {
- LayerDrawable background = (LayerDrawable) drawable;
- final int N = background.getNumberOfLayers();
- Drawable[] outDrawables = new Drawable[N];
-
- for (int i = 0; i < N; i++) {
- int id = background.getId(i);
- outDrawables[i] = tileify(background.getDrawable(i),
- (id == android.R.id.progress || id == android.R.id.secondaryProgress));
- }
-
- LayerDrawable newBg = new LayerDrawable(outDrawables);
-
- for (int i = 0; i < N; i++) {
- newBg.setId(i, background.getId(i));
- }
-
- return newBg;
-
- }/* else if (drawable instanceof StateListDrawable) {
- StateListDrawable in = (StateListDrawable) drawable;
- StateListDrawable out = new StateListDrawable();
- int numStates = in.getStateCount();
- for (int i = 0; i < numStates; i++) {
- out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip));
- }
- return out;
-
- }*/ else if (drawable instanceof BitmapDrawable) {
- final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
- if (mSampleTile == null) {
- mSampleTile = tileBitmap;
- }
-
- final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
-
- final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
- Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
- shapeDrawable.getPaint().setShader(bitmapShader);
-
- return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
- ClipDrawable.HORIZONTAL) : shapeDrawable;
- }
-
- return drawable;
- }
-
- Shape getDrawableShape() {
- final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
- return new RoundRectShape(roundedCorners, null, null);
- }
-
- /**
- * Convert a AnimationDrawable for use as a barberpole animation.
- * Each frame of the animation is wrapped in a ClipDrawable and
- * given a tiling BitmapShader.
- */
- private Drawable tileifyIndeterminate(Drawable drawable) {
- if (drawable instanceof AnimationDrawable) {
- AnimationDrawable background = (AnimationDrawable) drawable;
- final int N = background.getNumberOfFrames();
- AnimationDrawable newBg = new AnimationDrawable();
- newBg.setOneShot(background.isOneShot());
-
- for (int i = 0; i < N; i++) {
- Drawable frame = tileify(background.getFrame(i), true);
- frame.setLevel(10000);
- newBg.addFrame(frame, background.getDuration(i));
- }
- newBg.setLevel(10000);
- drawable = newBg;
- }
- return drawable;
- }
-
- /**
- * <p>
- * Initialize the progress bar's default values:
- * </p>
- * <ul>
- * <li>progress = 0</li>
- * <li>max = 100</li>
- * <li>animation duration = 4000 ms</li>
- * <li>indeterminate = false</li>
- * <li>behavior = repeat</li>
- * </ul>
- */
- private void initProgressBar() {
- mMax = 100;
- mProgress = 0;
- mSecondaryProgress = 0;
- mIndeterminate = false;
- mOnlyIndeterminate = false;
- mDuration = 4000;
- mBehavior = AlphaAnimation.RESTART;
- mMinWidth = 24;
- mMaxWidth = 48;
- mMinHeight = 24;
- mMaxHeight = 48;
- }
-
- /**
- * <p>Indicate whether this progress bar is in indeterminate mode.</p>
- *
- * @return true if the progress bar is in indeterminate mode
- */
- @ViewDebug.ExportedProperty(category = "progress")
- public synchronized boolean isIndeterminate() {
- return mIndeterminate;
- }
-
- /**
- * <p>Change the indeterminate mode for this progress bar. In indeterminate
- * mode, the progress is ignored and the progress bar shows an infinite
- * animation instead.</p>
- *
- * If this progress bar's style only supports indeterminate mode (such as the circular
- * progress bars), then this will be ignored.
- *
- * @param indeterminate true to enable the indeterminate mode
- */
- public synchronized void setIndeterminate(boolean indeterminate) {
- if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {
- mIndeterminate = indeterminate;
-
- if (indeterminate) {
- // swap between indeterminate and regular backgrounds
- mCurrentDrawable = mIndeterminateDrawable;
- startAnimation();
- } else {
- mCurrentDrawable = mProgressDrawable;
- stopAnimation();
- }
- }
- }
-
- /**
- * <p>Get the drawable used to draw the progress bar in
- * indeterminate mode.</p>
- *
- * @return a {@link android.graphics.drawable.Drawable} instance
- *
- * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable)
- * @see #setIndeterminate(boolean)
- */
- public Drawable getIndeterminateDrawable() {
- return mIndeterminateDrawable;
- }
-
- /**
- * <p>Define the drawable used to draw the progress bar in
- * indeterminate mode.</p>
- *
- * @param d the new drawable
- *
- * @see #getIndeterminateDrawable()
- * @see #setIndeterminate(boolean)
- */
- public void setIndeterminateDrawable(Drawable d) {
- if (d != null) {
- d.setCallback(this);
- }
- mIndeterminateDrawable = d;
- if (mIndeterminate) {
- mCurrentDrawable = d;
- postInvalidate();
- }
- }
-
- /**
- * <p>Get the drawable used to draw the progress bar in
- * progress mode.</p>
- *
- * @return a {@link android.graphics.drawable.Drawable} instance
- *
- * @see #setProgressDrawable(android.graphics.drawable.Drawable)
- * @see #setIndeterminate(boolean)
- */
- public Drawable getProgressDrawable() {
- return mProgressDrawable;
- }
-
- /**
- * <p>Define the drawable used to draw the progress bar in
- * progress mode.</p>
- *
- * @param d the new drawable
- *
- * @see #getProgressDrawable()
- * @see #setIndeterminate(boolean)
- */
- public void setProgressDrawable(Drawable d) {
- boolean needUpdate;
- if (mProgressDrawable != null && d != mProgressDrawable) {
- mProgressDrawable.setCallback(null);
- needUpdate = true;
- } else {
- needUpdate = false;
- }
-
- if (d != null) {
- d.setCallback(this);
-
- // Make sure the ProgressBar is always tall enough
- int drawableHeight = d.getMinimumHeight();
- if (mMaxHeight < drawableHeight) {
- mMaxHeight = drawableHeight;
- requestLayout();
- }
- }
- mProgressDrawable = d;
- if (!mIndeterminate) {
- mCurrentDrawable = d;
- postInvalidate();
- }
-
- if (needUpdate) {
- updateDrawableBounds(getWidth(), getHeight());
- updateDrawableState();
- doRefreshProgress(android.R.id.progress, mProgress, false, false);
- doRefreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false, false);
- }
- }
-
- /**
- * @return The drawable currently used to draw the progress bar
- */
- Drawable getCurrentDrawable() {
- return mCurrentDrawable;
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return who == mProgressDrawable || who == mIndeterminateDrawable
- || super.verifyDrawable(who);
- }
-
- @Override
- public void jumpDrawablesToCurrentState() {
- super.jumpDrawablesToCurrentState();
- if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState();
- if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState();
- }
-
- @Override
- public void postInvalidate() {
- if (!mNoInvalidate) {
- super.postInvalidate();
- }
- }
-
- private class RefreshProgressRunnable implements Runnable {
-
- private int mId;
- private int mProgress;
- private boolean mFromUser;
-
- RefreshProgressRunnable(int id, int progress, boolean fromUser) {
- mId = id;
- mProgress = progress;
- mFromUser = fromUser;
- }
-
- public void run() {
- doRefreshProgress(mId, mProgress, mFromUser, true);
- // Put ourselves back in the cache when we are done
- mRefreshProgressRunnable = this;
- }
-
- public void setup(int id, int progress, boolean fromUser) {
- mId = id;
- mProgress = progress;
- mFromUser = fromUser;
- }
-
- }
-
- private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
- boolean callBackToApp) {
- float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
- final Drawable d = mCurrentDrawable;
- if (d != null) {
- Drawable progressDrawable = null;
-
- if (d instanceof LayerDrawable) {
- progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id);
- }
-
- final int level = (int) (scale * MAX_LEVEL);
- (progressDrawable != null ? progressDrawable : d).setLevel(level);
- } else {
- invalidate();
- }
-
- if (callBackToApp && id == android.R.id.progress) {
- onProgressRefresh(scale, fromUser);
- }
- }
-
- void onProgressRefresh(float scale, boolean fromUser) {
- if (mAccessibilityManager.isEnabled()) {
- scheduleAccessibilityEventSender();
- }
- }
-
- private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
- if (mUiThreadId == Thread.currentThread().getId()) {
- doRefreshProgress(id, progress, fromUser, true);
- } else {
- RefreshProgressRunnable r;
- if (mRefreshProgressRunnable != null) {
- // Use cached RefreshProgressRunnable if available
- r = mRefreshProgressRunnable;
- // Uncache it
- mRefreshProgressRunnable = null;
- r.setup(id, progress, fromUser);
- } else {
- // Make a new one
- r = new RefreshProgressRunnable(id, progress, fromUser);
- }
- post(r);
- }
- }
-
- /**
- * <p>Set the current progress to the specified value. Does not do anything
- * if the progress bar is in indeterminate mode.</p>
- *
- * @param progress the new progress, between 0 and {@link #getMax()}
- *
- * @see #setIndeterminate(boolean)
- * @see #isIndeterminate()
- * @see #getProgress()
- * @see #incrementProgressBy(int)
- */
- public synchronized void setProgress(int progress) {
- setProgress(progress, false);
- }
-
- synchronized void setProgress(int progress, boolean fromUser) {
- if (mIndeterminate) {
- return;
- }
-
- if (progress < 0) {
- progress = 0;
- }
-
- if (progress > mMax) {
- progress = mMax;
- }
-
- if (progress != mProgress) {
- mProgress = progress;
- refreshProgress(android.R.id.progress, mProgress, fromUser);
- }
- }
-
- /**
- * <p>
- * Set the current secondary progress to the specified value. Does not do
- * anything if the progress bar is in indeterminate mode.
- * </p>
- *
- * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()}
- * @see #setIndeterminate(boolean)
- * @see #isIndeterminate()
- * @see #getSecondaryProgress()
- * @see #incrementSecondaryProgressBy(int)
- */
- public synchronized void setSecondaryProgress(int secondaryProgress) {
- if (mIndeterminate) {
- return;
- }
-
- if (secondaryProgress < 0) {
- secondaryProgress = 0;
- }
-
- if (secondaryProgress > mMax) {
- secondaryProgress = mMax;
- }
-
- if (secondaryProgress != mSecondaryProgress) {
- mSecondaryProgress = secondaryProgress;
- refreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false);
- }
- }
-
- /**
- * <p>Get the progress bar's current level of progress. Return 0 when the
- * progress bar is in indeterminate mode.</p>
- *
- * @return the current progress, between 0 and {@link #getMax()}
- *
- * @see #setIndeterminate(boolean)
- * @see #isIndeterminate()
- * @see #setProgress(int)
- * @see #setMax(int)
- * @see #getMax()
- */
- @ViewDebug.ExportedProperty(category = "progress")
- public synchronized int getProgress() {
- return mIndeterminate ? 0 : mProgress;
- }
-
- /**
- * <p>Get the progress bar's current level of secondary progress. Return 0 when the
- * progress bar is in indeterminate mode.</p>
- *
- * @return the current secondary progress, between 0 and {@link #getMax()}
- *
- * @see #setIndeterminate(boolean)
- * @see #isIndeterminate()
- * @see #setSecondaryProgress(int)
- * @see #setMax(int)
- * @see #getMax()
- */
- @ViewDebug.ExportedProperty(category = "progress")
- public synchronized int getSecondaryProgress() {
- return mIndeterminate ? 0 : mSecondaryProgress;
- }
-
- /**
- * <p>Return the upper limit of this progress bar's range.</p>
- *
- * @return a positive integer
- *
- * @see #setMax(int)
- * @see #getProgress()
- * @see #getSecondaryProgress()
- */
- @ViewDebug.ExportedProperty(category = "progress")
- public synchronized int getMax() {
- return mMax;
- }
-
- /**
- * <p>Set the range of the progress bar to 0...<tt>max</tt>.</p>
- *
- * @param max the upper range of this progress bar
- *
- * @see #getMax()
- * @see #setProgress(int)
- * @see #setSecondaryProgress(int)
- */
- public synchronized void setMax(int max) {
- if (max < 0) {
- max = 0;
- }
- if (max != mMax) {
- mMax = max;
- postInvalidate();
-
- if (mProgress > max) {
- mProgress = max;
- }
- refreshProgress(android.R.id.progress, mProgress, false);
- }
- }
-
- /**
- * <p>Increase the progress bar's progress by the specified amount.</p>
- *
- * @param diff the amount by which the progress must be increased
- *
- * @see #setProgress(int)
- */
- public synchronized final void incrementProgressBy(int diff) {
- setProgress(mProgress + diff);
- }
-
- /**
- * <p>Increase the progress bar's secondary progress by the specified amount.</p>
- *
- * @param diff the amount by which the secondary progress must be increased
- *
- * @see #setSecondaryProgress(int)
- */
- public synchronized final void incrementSecondaryProgressBy(int diff) {
- setSecondaryProgress(mSecondaryProgress + diff);
- }
-
- /**
- * <p>Start the indeterminate progress animation.</p>
- */
- void startAnimation() {
- if (getVisibility() != VISIBLE) {
- return;
- }
-
- if (mIndeterminateDrawable instanceof Animatable) {
- mShouldStartAnimationDrawable = true;
- mAnimation = null;
- } else {
- if (mInterpolator == null) {
- mInterpolator = new LinearInterpolator();
- }
-
- mTransformation = new Transformation();
- mAnimation = new AlphaAnimation(0.0f, 1.0f);
- mAnimation.setRepeatMode(mBehavior);
- mAnimation.setRepeatCount(Animation.INFINITE);
- mAnimation.setDuration(mDuration);
- mAnimation.setInterpolator(mInterpolator);
- mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
- }
- postInvalidate();
- }
-
- /**
- * <p>Stop the indeterminate progress animation.</p>
- */
- void stopAnimation() {
- mAnimation = null;
- mTransformation = null;
- if (mIndeterminateDrawable instanceof Animatable) {
- ((Animatable) mIndeterminateDrawable).stop();
- mShouldStartAnimationDrawable = false;
- }
- postInvalidate();
- }
-
- /**
- * Sets the acceleration curve for the indeterminate animation.
- * The interpolator is loaded as a resource from the specified context.
- *
- * @param context The application environment
- * @param resID The resource identifier of the interpolator to load
- */
- public void setInterpolator(Context context, int resID) {
- setInterpolator(AnimationUtils.loadInterpolator(context, resID));
- }
-
- /**
- * Sets the acceleration curve for the indeterminate animation.
- * Defaults to a linear interpolation.
- *
- * @param interpolator The interpolator which defines the acceleration curve
- */
- public void setInterpolator(Interpolator interpolator) {
- mInterpolator = interpolator;
- }
-
- /**
- * Gets the acceleration curve type for the indeterminate animation.
- *
- * @return the {@link Interpolator} associated to this animation
- */
- public Interpolator getInterpolator() {
- return mInterpolator;
- }
-
- @Override
- public void setVisibility(int v) {
- if (getVisibility() != v) {
- super.setVisibility(v);
-
- if (mIndeterminate) {
- // let's be nice with the UI thread
- if (v == GONE || v == INVISIBLE) {
- stopAnimation();
- } else {
- startAnimation();
- }
- }
- }
- }
-
- @Override
- protected void onVisibilityChanged(View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
-
- if (mIndeterminate) {
- // let's be nice with the UI thread
- if (visibility == GONE || visibility == INVISIBLE) {
- stopAnimation();
- } else {
- startAnimation();
- }
- }
- }
-
- @Override
- public void invalidateDrawable(Drawable dr) {
- if (!mInDrawing) {
- if (verifyDrawable(dr)) {
- final Rect dirty = dr.getBounds();
- final int scrollX = getScrollX() + getPaddingLeft();
- final int scrollY = getScrollY() + getPaddingTop();
-
- invalidate(dirty.left + scrollX, dirty.top + scrollY,
- dirty.right + scrollX, dirty.bottom + scrollY);
- } else {
- super.invalidateDrawable(dr);
- }
- }
- }
-
- /**
- * @hide
- *
- @Override
- public int getResolvedLayoutDirection(Drawable who) {
- return (who == mProgressDrawable || who == mIndeterminateDrawable) ?
- getResolvedLayoutDirection() : super.getResolvedLayoutDirection(who);
- }
- */
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- updateDrawableBounds(w, h);
- }
-
- private void updateDrawableBounds(int w, int h) {
- // onDraw will translate the canvas so we draw starting at 0,0
- int right = w - getPaddingRight() - getPaddingLeft();
- int bottom = h - getPaddingBottom() - getPaddingTop();
- int top = 0;
- int left = 0;
-
- if (mIndeterminateDrawable != null) {
- // Aspect ratio logic does not apply to AnimationDrawables
- if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) {
- // Maintain aspect ratio. Certain kinds of animated drawables
- // get very confused otherwise.
- final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth();
- final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight();
- final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight;
- final float boundAspect = (float) w / h;
- if (intrinsicAspect != boundAspect) {
- if (boundAspect > intrinsicAspect) {
- // New width is larger. Make it smaller to match height.
- final int width = (int) (h * intrinsicAspect);
- left = (w - width) / 2;
- right = left + width;
- } else {
- // New height is larger. Make it smaller to match width.
- final int height = (int) (w * (1 / intrinsicAspect));
- top = (h - height) / 2;
- bottom = top + height;
- }
- }
- }
- mIndeterminateDrawable.setBounds(0, 0, right - left, bottom - top);
- mIndeterminateRealLeft = left;
- mIndeterminateRealTop = top;
- }
-
- if (mProgressDrawable != null) {
- mProgressDrawable.setBounds(0, 0, right, bottom);
- }
- }
-
- @Override
- protected synchronized void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- Drawable d = mCurrentDrawable;
- if (d != null) {
- // Translate canvas so a indeterminate circular progress bar with padding
- // rotates properly in its animation
- canvas.save();
- canvas.translate(getPaddingLeft() + mIndeterminateRealLeft, getPaddingTop() + mIndeterminateRealTop);
- long time = getDrawingTime();
- if (mAnimation != null) {
- mAnimation.getTransformation(time, mTransformation);
- float scale = mTransformation.getAlpha();
- try {
- mInDrawing = true;
- d.setLevel((int) (scale * MAX_LEVEL));
- } finally {
- mInDrawing = false;
- }
- if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) {
- mLastDrawTime = SystemClock.uptimeMillis();
- postInvalidateDelayed(mAnimationResolution);
- }
- }
- d.draw(canvas);
- canvas.restore();
- if (mShouldStartAnimationDrawable && d instanceof Animatable) {
- ((Animatable) d).start();
- mShouldStartAnimationDrawable = false;
- }
- }
- }
-
- @Override
- protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- Drawable d = mCurrentDrawable;
-
- int dw = 0;
- int dh = 0;
- if (d != null) {
- dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
- dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight()));
- }
- updateDrawableState();
- dw += getPaddingLeft() + getPaddingRight();
- dh += getPaddingTop() + getPaddingBottom();
-
- if (IS_HONEYCOMB) {
- setMeasuredDimension(View.resolveSizeAndState(dw, widthMeasureSpec, 0),
- View.resolveSizeAndState(dh, heightMeasureSpec, 0));
- } else {
- setMeasuredDimension(View.resolveSize(dw, widthMeasureSpec),
- View.resolveSize(dh, heightMeasureSpec));
- }
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- updateDrawableState();
- }
-
- private void updateDrawableState() {
- int[] state = getDrawableState();
-
- if (mProgressDrawable != null && mProgressDrawable.isStateful()) {
- mProgressDrawable.setState(state);
- }
-
- if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) {
- mIndeterminateDrawable.setState(state);
- }
- }
-
- static class SavedState extends BaseSavedState {
- int progress;
- int secondaryProgress;
-
- /**
- * Constructor called from {@link IcsProgressBar#onSaveInstanceState()}
- */
- SavedState(Parcelable superState) {
- super(superState);
- }
-
- /**
- * Constructor called from {@link #CREATOR}
- */
- private SavedState(Parcel in) {
- super(in);
- progress = in.readInt();
- secondaryProgress = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(progress);
- out.writeInt(secondaryProgress);
- }
-
- public static final Parcelable.Creator<SavedState> CREATOR
- = new Parcelable.Creator<SavedState>() {
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
-
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
- }
-
- @Override
- public Parcelable onSaveInstanceState() {
- // Force our ancestor class to save its state
- Parcelable superState = super.onSaveInstanceState();
- SavedState ss = new SavedState(superState);
-
- ss.progress = mProgress;
- ss.secondaryProgress = mSecondaryProgress;
-
- return ss;
- }
-
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
-
- setProgress(ss.progress);
- setSecondaryProgress(ss.secondaryProgress);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (mIndeterminate) {
- startAnimation();
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if (mIndeterminate) {
- stopAnimation();
- }
- if(mRefreshProgressRunnable != null) {
- removeCallbacks(mRefreshProgressRunnable);
- }
- if (mAccessibilityEventSender != null) {
- removeCallbacks(mAccessibilityEventSender);
- }
- // This should come after stopAnimation(), otherwise an invalidate message remains in the
- // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation
- super.onDetachedFromWindow();
- }
-
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- event.setItemCount(mMax);
- event.setCurrentItemIndex(mProgress);
- }
-
- /**
- * Schedule a command for sending an accessibility event.
- * </br>
- * Note: A command is used to ensure that accessibility events
- * are sent at most one in a given time frame to save
- * system resources while the progress changes quickly.
- */
- private void scheduleAccessibilityEventSender() {
- if (mAccessibilityEventSender == null) {
- mAccessibilityEventSender = new AccessibilityEventSender();
- } else {
- removeCallbacks(mAccessibilityEventSender);
- }
- postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT);
- }
-
- /**
- * Command for sending an accessibility event.
- */
- private class AccessibilityEventSender implements Runnable {
- public void run() {
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- }
- }
-}