Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c11a489 authored by Jon Miranda's avatar Jon Miranda Committed by Jonathan Miranda
Browse files

Animates AbsSeekBar progress movement from key presses.

Change-Id: I9ef00c61351e8fe28be7a7a7d592f09a5124caa0
parent ccf9fca4
Loading
Loading
Loading
Loading
+54 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.widget;

import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -63,6 +64,9 @@ public abstract class AbsSeekBar extends ProgressBar {
     * progress.
     */
    private int mKeyProgressIncrement = 1;
    private ObjectAnimator mPositionAnimator;
    private static final int PROGRESS_ANIMATION_DURATION = 250;


    private static final int NO_ALPHA = 0xFF;
    private float mDisabledAlpha;
@@ -361,17 +365,16 @@ public abstract class AbsSeekBar extends ProgressBar {
    void onProgressRefresh(float scale, boolean fromUser) {
        super.onProgressRefresh(scale, fromUser);

        final Drawable thumb = mThumb;
        if (thumb != null) {
            setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);

            // Since we draw translated, the drawable's bounds that it signals
            // for invalidation won't be the actual bounds we want invalidated,
            // so just invalidate this whole view.
            invalidate();
        if (!isAnimationRunning()) {
            setThumbPos(scale);
        }
    }

    @Override
    void onAnimatePosition(float scale, boolean fromUser) {
        setThumbPos(scale);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
@@ -414,6 +417,18 @@ public abstract class AbsSeekBar extends ProgressBar {
        return max > 0 ? getProgress() / (float) max : 0;
    }

    private void setThumbPos(float scale) {
        final Drawable thumb = mThumb;
        if (thumb != null) {
            setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
            // Since we draw translated, the drawable's bounds that it signals
            // for invalidation won't be the actual bounds we want invalidated,
            // so just invalidate this whole view.
            invalidate();

        }
    }

    /**
     * Updates the thumb drawable bounds.
     *
@@ -676,13 +691,13 @@ public abstract class AbsSeekBar extends ProgressBar {
            switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    if (progress <= 0) break;
                    setProgress(progress - mKeyProgressIncrement, true);
                    animateSetProgress(progress - mKeyProgressIncrement);
                    onKeyChange();
                    return true;

                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    if (progress >= getMax()) break;
                    setProgress(progress + mKeyProgressIncrement, true);
                    animateSetProgress(progress + mKeyProgressIncrement);
                    onKeyChange();
                    return true;
            }
@@ -691,6 +706,35 @@ public abstract class AbsSeekBar extends ProgressBar {
        return super.onKeyDown(keyCode, event);
    }

    boolean isAnimationRunning() {
        return mPositionAnimator != null && mPositionAnimator.isRunning();
    }

    @Override
    public void setProgress(int progress, boolean fromUser) {
        if (isAnimationRunning()) {
            mPositionAnimator.cancel();
        }
        super.setProgress(progress, fromUser);
    }

    void animateSetProgress(int progress) {
        float curProgress = isAnimationRunning() ? getAnimationPosition() : getProgress();

        if (progress < 0) {
            progress = 0;
        } else if (progress > getMax()) {
            progress = getMax();
        }
        setProgressValueOnly(progress);

        mPositionAnimator = ObjectAnimator.ofFloat(this, "animationPosition", curProgress,
                progress);
        mPositionAnimator.setDuration(PROGRESS_ANIMATION_DURATION);
        mPositionAnimator.setAutoCancel(true);
        mPositionAnimator.start();
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(event);
+105 −52
Original line number Diff line number Diff line
@@ -242,6 +242,8 @@ public class ProgressBar extends View {
    private long mUiThreadId;
    private boolean mShouldStartAnimationDrawable;

    private float mAnimationPosition;

    private boolean mInDrawing;
    private boolean mAttached;
    private boolean mRefreshIsPosted;
@@ -1014,7 +1016,7 @@ public class ProgressBar extends View {
                final int count = mRefreshData.size();
                for (int i = 0; i < count; i++) {
                    final RefreshData rd = mRefreshData.get(i);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true, rd.animate);
                    rd.recycle();
                }
                mRefreshData.clear();
@@ -1029,10 +1031,12 @@ public class ProgressBar extends View {
                new SynchronizedPool<RefreshData>(POOL_MAX);

        public int id;
        public int progress;
        public float progress;
        public boolean fromUser;
        public boolean animate;

        public static RefreshData obtain(int id, int progress, boolean fromUser) {
        public static RefreshData obtain(int id, float progress, boolean fromUser,
                boolean animate) {
            RefreshData rd = sPool.acquire();
            if (rd == null) {
                rd = new RefreshData();
@@ -1040,6 +1044,7 @@ public class ProgressBar extends View {
            rd.id = id;
            rd.progress = progress;
            rd.fromUser = fromUser;
            rd.animate = animate;
            return rd;
        }

@@ -1064,9 +1069,19 @@ public class ProgressBar extends View {
        layer.mutate().setTint(tint, tintMode);
    }

    private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
    private float getScale(float progress) {
        return mMax > 0 ? progress / (float) mMax : 0;
    }

    private synchronized void doRefreshProgress(int id, float progress, boolean fromUser,
            boolean callBackToApp) {
        float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
        doRefreshProgress(id, progress, fromUser, callBackToApp, false);
    }

    private synchronized void doRefreshProgress(int id, float progress, boolean fromUser,
            boolean callBackToApp, boolean animate) {
        float scale = getScale(progress);

        final Drawable d = mCurrentDrawable;
        if (d != null) {
            Drawable progressDrawable = null;
@@ -1084,10 +1099,43 @@ public class ProgressBar extends View {
            invalidate();
        }

        if (callBackToApp && id == R.id.progress) {
        if (id == R.id.progress) {
            if (animate) {
                onAnimatePosition(scale, fromUser);
            } else if (callBackToApp) {
                onProgressRefresh(scale, fromUser);
            }
        }
    }

    /**
     * Called when a ProgressBar is animating its position.
     *
     * @param scale Current position/progress between 0 and 1.
     * @param fromUser True if the progress change was initiated by the user.
     */
    void onAnimatePosition(float scale, boolean fromUser) {
    }

    /**
     * Sets the progress value without going through the entire refresh process.
     *
     * @see #setProgress(int, boolean)
     * @param progress The new progress, between 0 and {@link #getMax()}
     */
    void setProgressValueOnly(int progress) {
        mProgress = progress;
        onProgressRefresh(getScale(progress), true);
    }

    void setAnimationPosition(float position) {
        mAnimationPosition = position;
        refreshProgress(R.id.progress, position, true, true);
    }

    float getAnimationPosition() {
        return mAnimationPosition;
    }

    void onProgressRefresh(float scale, boolean fromUser) {
        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
@@ -1095,15 +1143,20 @@ public class ProgressBar extends View {
        }
    }

    private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
    private synchronized void refreshProgress(int id, float progress, boolean fromUser) {
        refreshProgress(id, progress, fromUser, false);
    }

    private synchronized void refreshProgress(int id, float progress, boolean fromUser,
            boolean animate) {
        if (mUiThreadId == Thread.currentThread().getId()) {
            doRefreshProgress(id, progress, fromUser, true);
            doRefreshProgress(id, progress, fromUser, true, animate);
        } else {
            if (mRefreshProgressRunnable == null) {
                mRefreshProgressRunnable = new RefreshProgressRunnable();
            }

            final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
            final RefreshData rd = RefreshData.obtain(id, progress, fromUser, animate);
            mRefreshData.add(rd);
            if (mAttached && !mRefreshIsPosted) {
                post(mRefreshProgressRunnable);
@@ -1622,7 +1675,7 @@ public class ProgressBar extends View {
                final int count = mRefreshData.size();
                for (int i = 0; i < count; i++) {
                    final RefreshData rd = mRefreshData.get(i);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, rd.animate);
                    rd.recycle();
                }
                mRefreshData.clear();
+4 −0
Original line number Diff line number Diff line
@@ -314,6 +314,10 @@ public class RatingBar extends AbsSeekBar {
        dispatchRatingChange(true);
    }

    @Override
    void animateSetProgress(int progress) {
    }

    void dispatchRatingChange(boolean fromUser) {
        if (mOnRatingBarChangeListener != null) {
            mOnRatingBarChangeListener.onRatingChanged(this, getRating(),