package com.marshalchen.common.uimodule.customPullRefreshLayout.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import java.security.InvalidParameterException;
/**
* Created by baoyz on 14/10/31.
*/
class WaterDropDrawable extends RefreshDrawable implements Runnable {
private static final float MAX_LEVEL = 10000;
private static final float CIRCLE_COUNT = ProgressStates.values().length;
private static final float MAX_LEVEL_PER_CIRCLE = MAX_LEVEL / CIRCLE_COUNT;
private int mLevel;
private Point p1, p2, p3, p4;
private Paint mPaint;
private Path mPath;
private int mHeight;
private int mWidth;
private int mTop;
private int[] mColorSchemeColors;
private ProgressStates mCurrentState;
private Handler mHandler = new Handler();
private boolean isRunning;
private enum ProgressStates {
ONE,
TWO,
TREE,
FOUR
}
public WaterDropDrawable(Context context, PullRefreshLayout layout) {
super(context, layout);
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPath = new Path();
p1 = new Point();
p2 = new Point();
p3 = new Point();
p4 = new Point();
}
@Override
public void draw(Canvas canvas) {
canvas.save();
canvas.translate(0, mTop > 0 ? mTop : 0);
mPath.reset();
mPath.moveTo(p1.x, p1.y);
mPath.cubicTo(p3.x, p3.y, p4.x, p4.y, p2.x, p2.y);
canvas.drawPath(mPath, mPaint);
canvas.restore();
}
@Override
protected void onBoundsChange(Rect bounds) {
mWidth = bounds.width();
updateBounds();
super.onBoundsChange(bounds);
}
private void updateBounds() {
int height = mHeight;
int width = mWidth;
if (height > getRefreshLayout().getFinalOffset()) {
height = getRefreshLayout().getFinalOffset();
}
final float percent = height / (float) getRefreshLayout().getFinalOffset();
int offsetX = (int) (width / 2 * percent);
int offsetY = 0;
p1.set(offsetX, offsetY);
p2.set(width - offsetX, offsetY);
p3.set(width / 2 - height, height);
p4.set(width / 2 + height, height);
}
@Override
public void setColorSchemeColors(int[] colorSchemeColors) {
if (colorSchemeColors == null || colorSchemeColors.length < 4)
throw new InvalidParameterException("The color scheme length must be 4");
mPaint.setColor(colorSchemeColors[0]);
mColorSchemeColors = colorSchemeColors;
}
@Override
public void setPercent(float percent) {
mPaint.setColor(evaluate(percent, mColorSchemeColors[0], mColorSchemeColors[1]));
}
private void updateLevel(int level) {
int animationLevel = level == MAX_LEVEL ? 0 : level;
int stateForLevel = (int) (animationLevel / MAX_LEVEL_PER_CIRCLE);
mCurrentState = ProgressStates.values()[stateForLevel];
float percent = level % 2500 / 2500f;
int startColor = mColorSchemeColors[stateForLevel];
int endColor = mColorSchemeColors[(stateForLevel + 1) % ProgressStates.values().length];
mPaint.setColor(evaluate(percent, startColor, endColor));
}
@Override
public void offsetTopAndBottom(int offset) {
mHeight += offset;
mTop = mHeight - getRefreshLayout().getFinalOffset();
updateBounds();
invalidateSelf();
}
@Override
public void start() {
mLevel = 2500;
isRunning = true;
mHandler.postDelayed(this, 20);
}
@Override
public void stop() {
mHandler.removeCallbacks(this);
}
@Override
public boolean isRunning() {
return isRunning;
}
@Override
public void run() {
mLevel += 60;
if (mLevel > MAX_LEVEL)
mLevel = 0;
if (isRunning) {
mHandler.postDelayed(this, 20);
updateLevel(mLevel);
invalidateSelf();
}
}
private int evaluate(float fraction, int startValue, int endValue) {
int startInt = startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return ((startA + (int) (fraction * (endA - startA))) << 24) |
((startR + (int) (fraction * (endR - startR))) << 16) |
((startG + (int) (fraction * (endG - startG))) << 8) |
((startB + (int) (fraction * (endB - startB))));
}
}