Back to project page Android-Lib-SymmetricProgressBar.
The source code is released under:
Apache License
If you think the Android project Android-Lib-SymmetricProgressBar listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package android.lib.symmetricprogressbar; //w w w . j a v a 2 s. c om import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; public class SymmetricProgressBar extends View implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener { private final List<Integer> colors = new ArrayList<Integer>(4); private final List<Drawable> drawables = new ArrayList<Drawable>(this.colors.size()); private final List<ValueAnimator> animators = new ArrayList<ValueAnimator>(this.colors.size()); private Interpolator interpolator; private boolean animating; private boolean hasRepeated; private int duration; /** * Creates a new progress bar with range 0..100 and initial progress of 0. * @param context The application context. */ public SymmetricProgressBar(final Context context) { this(context, null); } public SymmetricProgressBar(final Context context, final AttributeSet attrs) { super(context, attrs); final TypedArray array; final int[] colors; if (attrs == null) { array = null; colors = context.getResources().getIntArray(R.array.SymmetricProgressBar_colors); } else { array = context.obtainStyledAttributes(attrs, R.styleable.SymmetricProgressBar); colors = context.getResources().getIntArray(array.getResourceId(R.styleable.SymmetricProgressBar_colors, R.array.SymmetricProgressBar_colors)); } for (final int color : colors) { this.colors.add(Integer.valueOf(color)); } final int interpolatorResId = array == null ? android.R.anim.decelerate_interpolator : array.getResourceId(R.styleable.SymmetricProgressBar_interpolator, android.R.anim.decelerate_interpolator); if (interpolatorResId > 0) { this.setInterpolator(context, interpolatorResId); } if (array != null) { this.setDuration(array.getInteger(R.styleable.SymmetricProgressBar_duration, context.getResources().getInteger(R.integer.SymmetricProgressBar_duration))); array.recycle(); } } /** * Gets the colors used to draw the progress bar in progress mode. */ public List<Integer> getColors() { return Collections.unmodifiableList(this.colors); } /** * Sets the colors used to draw the progress bar in progress mode. */ public void setColors(final Collection<Integer> colors) { this.colors.clear(); this.colors.addAll(colors); } /** * Gets the acceleration curve type for the indeterminate animation. * @return The {@link Interpolator} associated to this animation. */ public Interpolator getInterpolator() { return this.interpolator; } /** * Sets the acceleration curve for the indeterminate animation. * <p>The interpolator is loaded as a resource from the specified context.</p> * @param context The application context. * @param resId The resource identifier of the interpolator to load. */ public void setInterpolator(final Context context, final int resId) { this.setInterpolator(AnimationUtils.loadInterpolator(context, resId)); } /** * Sets the acceleration curve for the indeterminate animation. * <p>Defaults to a linear interpolation.</p> * @param interpolator The interpolator which defines the acceleration curve. */ public void setInterpolator(final Interpolator interpolator) { this.interpolator = interpolator; } public int getDuration() { return this.duration; } public void setDuration(final int duration) { this.duration = duration; } public boolean isAnimating() { return this.animating; } @Override public void setVisibility(final int visibility) { if (this.getVisibility() != visibility) { super.setVisibility(visibility); if (visibility == View.VISIBLE) { this.startAnimation(); } else { this.stopAnimation(); } } } public void startAnimation() { if (!this.animating) { this.animating = true; this.hasRepeated = false; for (final ValueAnimator animator : this.animators) { animator.removeAllListeners(); } this.drawables.clear(); this.animators.clear(); for (final int color : this.colors) { final Drawable drawable = new ColorDrawable(color); this.updateDrawables(this.getWidth(), this.getHeight()); this.drawables.add(drawable); this.animators.add(ValueAnimator.ofFloat(0, 1.1f)); } for (int i = 0; i < this.animators.size(); i++) { final ValueAnimator animator = this.animators.get(i); animator.setRepeatMode(Animation.RESTART); animator.setRepeatCount(Animation.INFINITE); animator.setDuration(this.duration / this.colors.size() * this.colors.size()); animator.setInterpolator(this.interpolator); animator.setStartDelay(i * this.duration / this.colors.size()); animator.addListener(this); animator.addUpdateListener(this); animator.start(); } if (this.getVisibility() == View.VISIBLE) { this.postInvalidate(); } } } public void stopAnimation() { this.animating = false; this.hasRepeated = false; for (final ValueAnimator animator : this.animators) { animator.end(); animator.removeAllListeners(); } this.postInvalidate(); } @Override public void onAnimationStart(final Animator animation) { } @Override public void onAnimationEnd(final Animator animation) { } @Override public void onAnimationCancel(final Animator animation) { } @Override public void onAnimationRepeat(final Animator animation) { synchronized (this.drawables) { synchronized (this.animators) { final int index = this.animators.indexOf(animation); this.drawables.add(this.drawables.remove(index)); this.animators.add(this.animators.remove(index)); } } this.hasRepeated = true; } @Override public void onAnimationUpdate(final ValueAnimator animation) { this.postInvalidate(); } @Override protected synchronized void onDraw(final Canvas canvas) { super.onDraw(canvas); if (this.animating) { synchronized (this.drawables) { synchronized (this.animators) { if (this.hasRepeated) { this.drawables.get(0).draw(canvas); } for (int i = 0; i < this.drawables.size(); i++) { final Drawable drawable = this.drawables.get(i); final float fraction = ((Float)this.animators.get(i).getAnimatedValue()).floatValue(); canvas.save(); canvas.clipRect(this.getWidth() / 2f * (1f - fraction), 0, this.getWidth() / 2f * (1f + fraction), this.getHeight()); drawable.draw(canvas); canvas.restore(); } } } } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); this.startAnimation(); } @Override protected void onDetachedFromWindow() { this.stopAnimation(); super.onDetachedFromWindow(); } @Override protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { this.updateDrawables(w, h); } private void updateDrawables(final int w, final int h) { for (final Drawable drawable : this.drawables) { drawable.setBounds(0, 0, w, h); } } }