package com.github.jdsjlzx.progressindicator;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Created by Jack Wang on 2016/8/5.
*/
public abstract class Indicator extends Drawable implements Animatable {
private HashMap<ValueAnimator,ValueAnimator.AnimatorUpdateListener> mUpdateListeners=new HashMap<>();
private ArrayList<ValueAnimator> mAnimators;
private int alpha = 255;
private static final Rect ZERO_BOUNDS_RECT = new Rect();
protected Rect drawBounds = ZERO_BOUNDS_RECT;
private boolean mHasAnimators;
private Paint mPaint=new Paint();
public Indicator(){
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
}
public int getColor() {
return mPaint.getColor();
}
public void setColor(int color) {
mPaint.setColor(color);
}
@Override
public void setAlpha(int alpha) {
this.alpha = alpha;
}
@Override
public int getAlpha() {
return alpha;
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public void draw(Canvas canvas) {
draw(canvas,mPaint);
}
public abstract void draw(Canvas canvas, Paint paint);
public abstract ArrayList<ValueAnimator> onCreateAnimators();
@Override
public void start() {
ensureAnimators();
if (mAnimators == null) {
return;
}
// If the animators has not ended, do nothing.
if (isStarted()) {
return;
}
startAnimators();
invalidateSelf();
}
private void startAnimators() {
for (int i = 0; i < mAnimators.size(); i++) {
ValueAnimator animator = mAnimators.get(i);
//when the animator restart , add the updateListener again because they
// was removed by animator stop .
ValueAnimator.AnimatorUpdateListener updateListener=mUpdateListeners.get(animator);
if (updateListener!=null){
animator.addUpdateListener(updateListener);
}
animator.start();
}
}
private void stopAnimators() {
if (mAnimators!=null){
for (ValueAnimator animator : mAnimators) {
if (animator != null && animator.isStarted()) {
animator.removeAllUpdateListeners();
animator.end();
}
}
}
}
private void ensureAnimators() {
if (!mHasAnimators) {
mAnimators = onCreateAnimators();
mHasAnimators = true;
}
}
@Override
public void stop() {
stopAnimators();
}
private boolean isStarted() {
for (ValueAnimator animator : mAnimators) {
return animator.isStarted();
}
return false;
}
@Override
public boolean isRunning() {
for (ValueAnimator animator : mAnimators) {
return animator.isRunning();
}
return false;
}
/**
* Your should use this to add AnimatorUpdateListener when
* create animator , otherwise , animator doesn't work when
* the animation restart .
* @param updateListener
*/
public void addUpdateListener(ValueAnimator animator, ValueAnimator.AnimatorUpdateListener updateListener){
mUpdateListeners.put(animator,updateListener);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
setDrawBounds(bounds);
}
public void setDrawBounds(Rect drawBounds) {
setDrawBounds(drawBounds.left, drawBounds.top, drawBounds.right, drawBounds.bottom);
}
public void setDrawBounds(int left, int top, int right, int bottom) {
this.drawBounds = new Rect(left, top, right, bottom);
}
public void postInvalidate(){
invalidateSelf();
}
public Rect getDrawBounds() {
return drawBounds;
}
public int getWidth(){
return drawBounds.width();
}
public int getHeight(){
return drawBounds.height();
}
public int centerX(){
return drawBounds.centerX();
}
public int centerY(){
return drawBounds.centerY();
}
public float exactCenterX(){
return drawBounds.exactCenterX();
}
public float exactCenterY(){
return drawBounds.exactCenterY();
}
}