package MyJar;
|
|
import android.animation.Animator;
|
import android.animation.ValueAnimator;
|
import android.content.Context;
|
import android.graphics.Canvas;
|
import android.graphics.ColorFilter;
|
import android.graphics.Rect;
|
import android.graphics.RectF;
|
import android.graphics.drawable.Drawable;
|
import android.os.Handler;
|
import android.os.Looper;
|
import android.util.Log;
|
import android.view.animation.Animation;
|
import android.view.animation.LinearInterpolator;
|
|
|
public abstract class LoadingRenderer {
|
private static final long ANIMATION_DURATION = 1333;
|
private static final float DEFAULT_SIZE = 56.0f;
|
|
private final ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener
|
= new ValueAnimator.AnimatorUpdateListener() {
|
@Override
|
public void onAnimationUpdate(ValueAnimator animation) {
|
computeRender((float) animation.getAnimatedValue());
|
invalidateSelf();
|
}
|
};
|
|
/**
|
* Whenever {@link LoadingDrawable} boundary changes mBounds will be updated.
|
* More details you can see {@link LoadingDrawable#onBoundsChange(Rect)}
|
*/
|
protected final Rect mBounds = new Rect();
|
|
private Drawable.Callback mCallback;
|
private ValueAnimator mRenderAnimator;
|
|
protected long mDuration;
|
|
protected float mWidth;
|
protected float mHeight;
|
|
public LoadingRenderer(Context context) {
|
initParams(context);
|
setupAnimators();
|
}
|
|
@Deprecated
|
protected void draw(Canvas canvas, Rect bounds) {
|
}
|
|
protected void draw(Canvas canvas) {
|
draw(canvas, mBounds);
|
}
|
|
protected abstract void computeRender(float renderProgress);
|
|
protected abstract void setAlpha(int alpha);
|
|
protected abstract void setColorFilter(ColorFilter cf);
|
|
protected abstract void reset();
|
|
protected void addRenderListener(Animator.AnimatorListener animatorListener) {
|
mRenderAnimator.addListener(animatorListener);
|
}
|
|
void start() {
|
reset();
|
mRenderAnimator.addUpdateListener(mAnimatorUpdateListener);
|
|
mRenderAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
mRenderAnimator.setDuration(mDuration);
|
mRenderAnimator.start();
|
}
|
|
void stop() {
|
// if I just call mRenderAnimator.end(),
|
// it will always call the method onAnimationUpdate(ValueAnimator animation)
|
// why ? if you know why please send email to me (dinus_developer@163.com)
|
mRenderAnimator.removeUpdateListener(mAnimatorUpdateListener);
|
|
mRenderAnimator.setRepeatCount(0);
|
mRenderAnimator.setDuration(0);
|
mRenderAnimator.end();
|
}
|
|
boolean isRunning() {
|
return mRenderAnimator.isRunning();
|
}
|
|
void setCallback(Drawable.Callback callback) {
|
this.mCallback = callback;
|
}
|
|
void setBounds(Rect bounds) {
|
mBounds.set(bounds);
|
}
|
|
private void initParams(Context context) {
|
mWidth = DensityUtil.dip2px(context, DEFAULT_SIZE);
|
mHeight = DensityUtil.dip2px(context, DEFAULT_SIZE);
|
|
mDuration = ANIMATION_DURATION;
|
}
|
|
private void setupAnimators() {
|
mRenderAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
|
mRenderAnimator.setRepeatCount(Animation.INFINITE);
|
mRenderAnimator.setRepeatMode(Animation.RESTART);
|
mRenderAnimator.setDuration(mDuration);
|
//fuck you! the default interpolator is AccelerateDecelerateInterpolator
|
mRenderAnimator.setInterpolator(new LinearInterpolator());
|
mRenderAnimator.addUpdateListener(mAnimatorUpdateListener);
|
}
|
|
private void invalidateSelf() {
|
mCallback.invalidateDrawable(null);
|
}
|
|
}
|