package com.llf.basemodel.recycleview;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* Created by llf on 2017/1/5.
* 底部加载转圈的view
*/
public class LoadingView extends View {
private static final String TAG = LoadingView.class.getSimpleName();
private int width, height;
private float radius;
private Paint mPaint;
private Path mPath, dst;
private int circleWidth;
private PathMeasure mPathMeasure;
private float mAnimatorValue = 0;
private ValueAnimator mValueAnimator;//属性动画
public LoadingView(Context context) {
this(context, null);
}
public LoadingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
circleWidth = dpTpPx(4);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeWidth(circleWidth);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.parseColor("#ffff4444"));
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPath = new Path();
dst = new Path();
mPathMeasure = new PathMeasure();
mValueAnimator = ValueAnimator.ofFloat(0, 1);
mValueAnimator.setDuration(1200);
mValueAnimator.setInterpolator(new LinearInterpolator());
mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimatorValue = (float) animation.getAnimatedValue();
invalidate();
}
});
mValueAnimator.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int resultWidth = 500;
int resultHeight = 500;
if (widthMode == MeasureSpec.EXACTLY) {
resultWidth = widthSize;
} else {
resultWidth = Math.min(resultWidth, widthSize);
}
if (heightMode == MeasureSpec.EXACTLY) {
resultHeight = heightSize;
} else {
resultHeight = Math.min(resultHeight, heightSize);
}
setMeasuredDimension(resultWidth, resultHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w;
height = h;
radius = Math.min(w, h) / 2;
mPath.addCircle(width / 2, height / 2, radius - circleWidth, Path.Direction.CCW);
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
dst.reset();
mPathMeasure.setPath(mPath, false);
float stop = mPathMeasure.getLength() * mAnimatorValue;
float start = (float) (stop - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * 200f));
mPathMeasure.getSegment(start, stop, dst, true);
canvas.drawPath(dst, mPaint);
}
private int dpTpPx(float value) {
DisplayMetrics dm = getResources().getDisplayMetrics();
return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm) + 0.5);
}
}