package moe.codeest.enviews;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AnticipateInterpolator;
import com.shuyu.gsyvideoplayer.R;
/**
* Created by codeest on 16/11/7.
*
*/
public class ENPlayView extends View {
public static int STATE_PLAY = 0;
public static int STATE_PAUSE = 1;
public static int DEFAULT_LINE_COLOR = Color.WHITE;
public static int DEFAULT_BG_LINE_COLOR = 0xfffafafa;
public static int DEFAULT_LINE_WIDTH = 4;
public static int DEFAULT_BG_LINE_WIDTH = 4;
public static int DEFAULT_DURATION = 1200;
private int mCurrentState = STATE_PAUSE;
private Paint mPaint, mBgPaint;
private int mWidth, mHeight;
private int mCenterX, mCenterY;
private int mCircleRadius;
private RectF mRectF, mBgRectF;
private float mFraction = 1;
private Path mPath, mDstPath;
private PathMeasure mPathMeasure;
private float mPathLength;
private int mDuration;
public ENPlayView(Context context) {
super(context);
}
public ENPlayView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.play);
int lineColor = ta.getColor(R.styleable.play_play_line_color, DEFAULT_LINE_COLOR);
int bgLineColor = ta.getColor(R.styleable.play_play_bg_line_color, DEFAULT_BG_LINE_COLOR);
int lineWidth = ta.getInteger(R.styleable.play_play_line_width, dp2px(DEFAULT_LINE_WIDTH));
int bgLineWidth = ta.getInteger(R.styleable.play_play_bg_line_width, dp2px(DEFAULT_BG_LINE_WIDTH));
ta.recycle();
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(lineColor);
mPaint.setStrokeWidth(lineWidth);
mPaint.setPathEffect(new CornerPathEffect(1));
mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBgPaint.setStyle(Paint.Style.STROKE);
mBgPaint.setStrokeCap(Paint.Cap.ROUND);
mBgPaint.setColor(bgLineColor);
mBgPaint.setStrokeWidth(bgLineWidth);
mPath = new Path();
mDstPath = new Path();
mPathMeasure = new PathMeasure();
mDuration = DEFAULT_DURATION;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w * 9 / 10;
mHeight = h * 9 / 10;
mCircleRadius = mWidth / dp2px(4);
mCenterX = w / 2;
mCenterY = h / 2;
mRectF = new RectF(mCenterX - mCircleRadius, mCenterY + 0.6f * mCircleRadius,
mCenterX + mCircleRadius, mCenterY + 2.6f * mCircleRadius);
mBgRectF = new RectF(mCenterX - mWidth / 2 ,mCenterY - mHeight / 2 ,mCenterX + mWidth / 2, mCenterY + mHeight / 2);
mPath.moveTo(mCenterX - mCircleRadius, mCenterY + 1.8f * mCircleRadius);
mPath.lineTo(mCenterX - mCircleRadius, mCenterY - 1.8f * mCircleRadius);
mPath.lineTo(mCenterX + mCircleRadius, mCenterY);
mPath.close();
mPathMeasure.setPath(mPath, false);
mPathLength = mPathMeasure.getLength();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCenterX, mCenterY, mWidth / 2, mBgPaint);
if (mFraction < 0) { //嗷~~ 弹性部分
canvas.drawLine(mCenterX + mCircleRadius, mCenterY - 1.6f * mCircleRadius + 10 * mCircleRadius * mFraction,
mCenterX + mCircleRadius, mCenterY + 1.6f * mCircleRadius + 10 * mCircleRadius * mFraction, mPaint);
canvas.drawLine(mCenterX - mCircleRadius, mCenterY - 1.6f * mCircleRadius,
mCenterX - mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);
canvas.drawArc(mBgRectF, -105 , 360 , false, mPaint);
} else if (mFraction <= 0.3) { //嗷~~ 右侧直线和下方曲线
canvas.drawLine(mCenterX + mCircleRadius, mCenterY - 1.6f * mCircleRadius + mCircleRadius * 3.2f / 0.3f * mFraction,
mCenterX + mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);
canvas.drawLine(mCenterX - mCircleRadius, mCenterY - 1.6f * mCircleRadius,
mCenterX - mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);
if (mFraction != 0)
canvas.drawArc(mRectF, 0f, 180f / 0.3f * mFraction, false, mPaint);
canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
} else if (mFraction <= 0.6) { //嗷~~ 下方曲线和三角形
canvas.drawArc(mRectF, 180f / 0.3f * (mFraction - 0.3f), 180 - 180f / 0.3f * (mFraction - 0.3f), false , mPaint);
mDstPath.reset();
//mDstPath.lineTo(0 ,0);
mPathMeasure.getSegment(0.02f * mPathLength, 0.38f * mPathLength + 0.42f * mPathLength / 0.3f * (mFraction - 0.3f) ,
mDstPath, true);
canvas.drawPath(mDstPath, mPaint);
canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
} else if (mFraction <= 0.8) { //嗷~~ 三角形
mDstPath.reset();
//mDstPath.lineTo(0 ,0);
mPathMeasure.getSegment(0.02f * mPathLength + 0.2f * mPathLength / 0.2f * (mFraction - 0.6f)
, 0.8f * mPathLength + 0.2f * mPathLength / 0.2f * (mFraction - 0.6f) ,
mDstPath, true);
canvas.drawPath(mDstPath, mPaint);
canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
} else { //嗷~~ 弹性部分
mDstPath.reset();
//mDstPath.lineTo(0 ,0);
mPathMeasure.getSegment(10 * mCircleRadius * (mFraction - 1)
, mPathLength ,
mDstPath, true);
canvas.drawPath(mDstPath, mPaint);
}
}
public void play() {
if (mCurrentState == STATE_PLAY) {
return;
}
mCurrentState = STATE_PLAY;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.f, 100.f);
valueAnimator.setDuration(mDuration);
valueAnimator.setInterpolator(new AnticipateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mFraction = 1 - valueAnimator.getAnimatedFraction();
invalidate();
}
});
if (!valueAnimator.isRunning()) {
valueAnimator.start();
}
}
public void pause() {
if (mCurrentState == STATE_PAUSE) {
return;
}
mCurrentState = STATE_PAUSE;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.f, 100.f);
valueAnimator.setDuration(mDuration);
valueAnimator.setInterpolator(new AnticipateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mFraction = valueAnimator.getAnimatedFraction();
invalidate();
}
});
if (!valueAnimator.isRunning()) {
valueAnimator.start();
}
}
public int getCurrentState() {
return mCurrentState;
}
public void setDuration(int duration) {
mDuration = duration;
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}
}