diff options
author | RoboErik <epastern@google.com> | 2015-02-11 13:52:05 -0800 |
---|---|---|
committer | RoboErik <epastern@google.com> | 2015-02-11 13:52:05 -0800 |
commit | 5b07143e36096168fd95d8e27988b233b2a70ece (patch) | |
tree | 2c8d56235a153d11a9402c4638e773c329fcb439 /core | |
parent | 7d85bc4c435bc37284a814fb8baf53980396ab5b (diff) | |
download | frameworks_base-5b07143e36096168fd95d8e27988b233b2a70ece.zip frameworks_base-5b07143e36096168fd95d8e27988b233b2a70ece.tar.gz frameworks_base-5b07143e36096168fd95d8e27988b233b2a70ece.tar.bz2 |
Pass the new progress when updating a ProgressBar
There was a race condition where the update for a progress change
from the user could pass the wrong progress value causing apps to
treat a non-user update as a user update.
bug:18515012
Change-Id: Ia62a1d07cd15f99effbf644642307c71049748f2
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/widget/AbsSeekBar.java | 4 | ||||
-rw-r--r-- | core/java/android/widget/ProgressBar.java | 103 | ||||
-rw-r--r-- | core/java/android/widget/RatingBar.java | 70 | ||||
-rw-r--r-- | core/java/android/widget/SeekBar.java | 32 |
4 files changed, 105 insertions, 104 deletions
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 4f6ea23..78344ac 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -381,8 +381,8 @@ public abstract class AbsSeekBar extends ProgressBar { } @Override - void onProgressRefresh(float scale, boolean fromUser) { - super.onProgressRefresh(scale, fromUser); + void onProgressRefresh(float scale, boolean fromUser, int progress) { + super.onProgressRefresh(scale, fromUser, progress); final Drawable thumb = mThumb; if (thumb != null) { diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 9c3296b..5b0745e 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -18,6 +18,7 @@ package android.widget; import android.annotation.Nullable; import android.graphics.PorterDuff; + import com.android.internal.R; import android.content.Context; @@ -64,8 +65,8 @@ import java.util.ArrayList; /** * <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 + * 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. @@ -81,7 +82,7 @@ import java.util.ArrayList; * <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; @@ -169,13 +170,13 @@ import java.util.ArrayList; * </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}, + * + * <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 @@ -244,7 +245,7 @@ public class ProgressBar extends View { public ProgressBar(Context context) { this(context, null); } - + public ProgressBar(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.progressBarStyle); } @@ -261,9 +262,9 @@ public class ProgressBar extends View { final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.ProgressBar, defStyleAttr, defStyleRes); - + mNoInvalidate = true; - + final Drawable progressDrawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable); if (progressDrawable != null) { // Calling this method can set mMaxHeight, make sure the corresponding @@ -282,11 +283,11 @@ public class ProgressBar extends View { mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior); final int resID = a.getResourceId( - com.android.internal.R.styleable.ProgressBar_interpolator, + 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)); @@ -399,12 +400,12 @@ public class ProgressBar extends View { * 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), @@ -412,13 +413,13 @@ public class ProgressBar extends View { } 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(); @@ -427,7 +428,7 @@ public class ProgressBar extends View { out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip)); } return out; - + } else if (drawable instanceof BitmapDrawable) { final BitmapDrawable bitmap = (BitmapDrawable) drawable; final Bitmap tileBitmap = bitmap.getBitmap(); @@ -448,7 +449,7 @@ public class ProgressBar extends View { return clip ? new ClipDrawable( shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable; } - + return drawable; } @@ -456,7 +457,7 @@ public class ProgressBar extends View { 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 @@ -468,7 +469,7 @@ public class ProgressBar extends View { 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); @@ -479,7 +480,7 @@ public class ProgressBar extends View { } return drawable; } - + /** * <p> * Initialize the progress bar's default values: @@ -520,7 +521,7 @@ public class ProgressBar extends View { * <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. * @@ -699,7 +700,7 @@ public class ProgressBar extends View { setIndeterminateDrawable(d); } - + /** * <p>Get the drawable used to draw the progress bar in * progress mode.</p> @@ -1135,7 +1136,7 @@ public class ProgressBar extends View { setProgressDrawable(d); } - + /** * @return The drawable currently used to draw the progress bar */ @@ -1214,7 +1215,7 @@ public class ProgressBar extends View { rd.fromUser = fromUser; return rd; } - + public void recycle() { sPool.release(this); } @@ -1257,13 +1258,13 @@ public class ProgressBar extends View { } else { invalidate(); } - + if (callBackToApp && id == R.id.progress) { - onProgressRefresh(scale, fromUser); + onProgressRefresh(scale, fromUser, progress); } } - void onProgressRefresh(float scale, boolean fromUser) { + void onProgressRefresh(float scale, boolean fromUser, int progress) { if (AccessibilityManager.getInstance(mContext).isEnabled()) { scheduleAccessibilityEventSender(); } @@ -1285,7 +1286,7 @@ public class ProgressBar extends View { } } } - + /** * <p>Set the current progress to the specified value. Does not do anything * if the progress bar is in indeterminate mode.</p> @@ -1295,13 +1296,13 @@ public class ProgressBar extends View { * @see #setIndeterminate(boolean) * @see #isIndeterminate() * @see #getProgress() - * @see #incrementProgressBy(int) + * @see #incrementProgressBy(int) */ @android.view.RemotableViewMethod public synchronized void setProgress(int progress) { setProgress(progress, false); } - + @android.view.RemotableViewMethod synchronized void setProgress(int progress, boolean fromUser) { if (mIndeterminate) { @@ -1327,7 +1328,7 @@ public class ProgressBar extends View { * 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() @@ -1408,8 +1409,8 @@ public class ProgressBar extends View { * @param max the upper range of this progress bar * * @see #getMax() - * @see #setProgress(int) - * @see #setSecondaryProgress(int) + * @see #setProgress(int) + * @see #setSecondaryProgress(int) */ @android.view.RemotableViewMethod public synchronized void setMax(int max) { @@ -1426,13 +1427,13 @@ public class ProgressBar extends View { refreshProgress(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) + * @see #setProgress(int) */ public synchronized final void incrementProgressBy(int diff) { setProgress(mProgress + diff); @@ -1443,7 +1444,7 @@ public class ProgressBar extends View { * * @param diff the amount by which the secondary progress must be increased * - * @see #setSecondaryProgress(int) + * @see #setSecondaryProgress(int) */ public synchronized final void incrementSecondaryProgressBy(int diff) { setSecondaryProgress(mSecondaryProgress + diff); @@ -1466,13 +1467,13 @@ public class ProgressBar extends View { if (mInterpolator == null) { mInterpolator = new LinearInterpolator(); } - + if (mTransformation == null) { mTransformation = new Transformation(); } else { mTransformation.clear(); } - + if (mAnimation == null) { mAnimation = new AlphaAnimation(0.0f, 1.0f); } else { @@ -1623,7 +1624,7 @@ public class ProgressBar extends View { } mIndeterminateDrawable.setBounds(left, top, right, bottom); } - + if (mProgressDrawable != null) { mProgressDrawable.setBounds(0, 0, right, bottom); } @@ -1693,20 +1694,20 @@ public class ProgressBar extends View { setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0), resolveSizeAndState(dh, heightMeasureSpec, 0)); } - + @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); } @@ -1728,14 +1729,14 @@ public class ProgressBar extends View { static class SavedState extends BaseSavedState { int progress; int secondaryProgress; - + /** * Constructor called from {@link ProgressBar#onSaveInstanceState()} */ SavedState(Parcelable superState) { super(superState); } - + /** * Constructor called from {@link #CREATOR} */ @@ -1769,10 +1770,10 @@ public class ProgressBar extends View { // 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; } @@ -1780,7 +1781,7 @@ public class ProgressBar extends View { public void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); - + setProgress(ss.progress); setSecondaryProgress(ss.secondaryProgress); } diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java index 4268961..f18e372 100644 --- a/core/java/android/widget/RatingBar.java +++ b/core/java/android/widget/RatingBar.java @@ -43,7 +43,7 @@ import com.android.internal.R; * <p> * The secondary progress should not be modified by the client as it is used * internally as the background for a fractionally filled star. - * + * * @attr ref android.R.styleable#RatingBar_numStars * @attr ref android.R.styleable#RatingBar_rating * @attr ref android.R.styleable#RatingBar_stepSize @@ -58,14 +58,14 @@ public class RatingBar extends AbsSeekBar { * programmatically. */ public interface OnRatingBarChangeListener { - + /** * Notification that the rating has changed. Clients can use the * fromUser parameter to distinguish user-initiated changes from those * that occurred programmatically. This will not be called continuously * while the user is dragging, only when the user finalizes a rating by * lifting the touch. - * + * * @param ratingBar The RatingBar whose rating has changed. * @param rating The current rating. This will be in the range * 0..numStars. @@ -79,9 +79,9 @@ public class RatingBar extends AbsSeekBar { private int mNumStars = 5; private int mProgressOnStartTracking; - + private OnRatingBarChangeListener mOnRatingBarChangeListener; - + public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } @@ -98,19 +98,19 @@ public class RatingBar extends AbsSeekBar { a.recycle(); if (numStars > 0 && numStars != mNumStars) { - setNumStars(numStars); + setNumStars(numStars); } - + if (stepSize >= 0) { setStepSize(stepSize); } else { setStepSize(0.5f); } - + if (rating >= 0) { setRating(rating); } - + // A touch inside a star fill up to that fractional area (slightly more // than 1 so boundaries round up). mTouchProgressOffset = 1.1f; @@ -123,16 +123,16 @@ public class RatingBar extends AbsSeekBar { public RatingBar(Context context) { this(context, null); } - + /** * Sets the listener to be called when the rating changes. - * + * * @param listener The listener. */ public void setOnRatingBarChangeListener(OnRatingBarChangeListener listener) { mOnRatingBarChangeListener = listener; } - + /** * @return The listener (may be null) that is listening for rating change * events. @@ -144,7 +144,7 @@ public class RatingBar extends AbsSeekBar { /** * Whether this rating bar should only be an indicator (thus non-changeable * by the user). - * + * * @param isIndicator Whether it should be an indicator. * * @attr ref android.R.styleable#RatingBar_isIndicator @@ -153,7 +153,7 @@ public class RatingBar extends AbsSeekBar { mIsUserSeekable = !isIndicator; setFocusable(!isIndicator); } - + /** * @return Whether this rating bar is only an indicator. * @@ -162,21 +162,21 @@ public class RatingBar extends AbsSeekBar { public boolean isIndicator() { return !mIsUserSeekable; } - + /** * Sets the number of stars to show. In order for these to be shown * properly, it is recommended the layout width of this widget be wrap * content. - * + * * @param numStars The number of stars. */ public void setNumStars(final int numStars) { if (numStars <= 0) { return; } - + mNumStars = numStars; - + // This causes the width to change, so re-layout requestLayout(); } @@ -188,10 +188,10 @@ public class RatingBar extends AbsSeekBar { public int getNumStars() { return mNumStars; } - + /** * Sets the rating (the number of stars filled). - * + * * @param rating The rating to set. */ public void setRating(float rating) { @@ -200,16 +200,16 @@ public class RatingBar extends AbsSeekBar { /** * Gets the current rating (number of stars filled). - * + * * @return The current rating. */ public float getRating() { - return getProgress() / getProgressPerStar(); + return getProgress() / getProgressPerStar(); } /** * Sets the step size (granularity) of this rating bar. - * + * * @param stepSize The step size of this rating bar. For example, if * half-star granularity is wanted, this would be 0.5. */ @@ -217,7 +217,7 @@ public class RatingBar extends AbsSeekBar { if (stepSize <= 0) { return; } - + final float newMax = mNumStars / stepSize; final int newProgress = (int) (newMax / getMax() * getProgress()); setMax((int) newMax); @@ -226,13 +226,13 @@ public class RatingBar extends AbsSeekBar { /** * Gets the step size of this rating bar. - * + * * @return The step size. */ public float getStepSize() { return (float) getNumStars() / getMax(); } - + /** * @return The amount of progress that fits into a star */ @@ -251,12 +251,12 @@ public class RatingBar extends AbsSeekBar { } @Override - void onProgressRefresh(float scale, boolean fromUser) { - super.onProgressRefresh(scale, fromUser); + void onProgressRefresh(float scale, boolean fromUser, int progress) { + super.onProgressRefresh(scale, fromUser, progress); // Keep secondary progress in sync with primary - updateSecondaryProgress(getProgress()); - + updateSecondaryProgress(progress); + if (!fromUser) { // Callback for non-user rating changes dispatchRatingChange(false); @@ -267,7 +267,7 @@ public class RatingBar extends AbsSeekBar { * The secondary progress is used to differentiate the background of a * partially filled star. This method keeps the secondary progress in sync * with the progress. - * + * * @param progress The primary progress level. */ private void updateSecondaryProgress(int progress) { @@ -278,11 +278,11 @@ public class RatingBar extends AbsSeekBar { setSecondaryProgress(secondaryProgress); } } - + @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - + if (mSampleTile != null) { // TODO: Once ProgressBar's TODOs are gone, this can be done more // cleanly than mSampleTile @@ -295,7 +295,7 @@ public class RatingBar extends AbsSeekBar { @Override void onStartTrackingTouch() { mProgressOnStartTracking = getProgress(); - + super.onStartTrackingTouch(); } @@ -327,7 +327,7 @@ public class RatingBar extends AbsSeekBar { if (max <= 0) { return; } - + super.setMax(max); } diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java index e97bdf2..fc070e7 100644 --- a/core/java/android/widget/SeekBar.java +++ b/core/java/android/widget/SeekBar.java @@ -26,7 +26,7 @@ import android.view.accessibility.AccessibilityNodeInfo; /** * A SeekBar is an extension of ProgressBar that adds a draggable thumb. The user can touch * the thumb and drag left or right to set the current progress level or use the arrow keys. - * Placing focusable widgets to the left or right of a SeekBar is discouraged. + * Placing focusable widgets to the left or right of a SeekBar is discouraged. * <p> * Clients of the SeekBar can attach a {@link SeekBar.OnSeekBarChangeListener} to * be notified of the user's actions. @@ -42,39 +42,39 @@ public class SeekBar extends AbsSeekBar { * programmatically. */ public interface OnSeekBarChangeListener { - + /** * Notification that the progress level has changed. Clients can use the fromUser parameter * to distinguish user-initiated changes from those that occurred programmatically. - * + * * @param seekBar The SeekBar whose progress has changed * @param progress The current progress level. This will be in the range 0..max where max * was set by {@link ProgressBar#setMax(int)}. (The default value for max is 100.) * @param fromUser True if the progress change was initiated by the user. */ void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser); - + /** * Notification that the user has started a touch gesture. Clients may want to use this - * to disable advancing the seekbar. + * to disable advancing the seekbar. * @param seekBar The SeekBar in which the touch gesture began */ void onStartTrackingTouch(SeekBar seekBar); - + /** * Notification that the user has finished a touch gesture. Clients may want to use this - * to re-enable advancing the seekbar. + * to re-enable advancing the seekbar. * @param seekBar The SeekBar in which the touch gesture began */ void onStopTrackingTouch(SeekBar seekBar); } private OnSeekBarChangeListener mOnSeekBarChangeListener; - + public SeekBar(Context context) { this(context, null); } - + public SeekBar(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.seekBarStyle); } @@ -88,26 +88,26 @@ public class SeekBar extends AbsSeekBar { } @Override - void onProgressRefresh(float scale, boolean fromUser) { - super.onProgressRefresh(scale, fromUser); + void onProgressRefresh(float scale, boolean fromUser, int progress) { + super.onProgressRefresh(scale, fromUser, progress); if (mOnSeekBarChangeListener != null) { - mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser); + mOnSeekBarChangeListener.onProgressChanged(this, progress, fromUser); } } /** * Sets a listener to receive notifications of changes to the SeekBar's progress level. Also * provides notifications of when the user starts and stops a touch gesture within the SeekBar. - * + * * @param l The seek bar notification listener - * + * * @see SeekBar.OnSeekBarChangeListener */ public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) { mOnSeekBarChangeListener = l; } - + @Override void onStartTrackingTouch() { super.onStartTrackingTouch(); @@ -115,7 +115,7 @@ public class SeekBar extends AbsSeekBar { mOnSeekBarChangeListener.onStartTrackingTouch(this); } } - + @Override void onStopTrackingTouch() { super.onStopTrackingTouch(); |