public class JiondongView extends View {
private Paint mBackgroundPaint;
private float mScaledDensity;
//背景的宽与高
private int mBgWidth;
private int mBgHeight;
//屏幕的宽与高
private int mMeasureWidth=0;
private int mMeasureHeight=0;
//圆角
private int mBgRx;
private int mBgRy;
private RectF mBgRectF;
//误差
private int flag;
private Paint mTextdPaint;
private String mMsgText="!";
private float mMsgTextLength;
private float mMsgTextHeight;
private Paint mCirclPaint;
private Paint mCirclRingPaint;
//默认view的宽度
private int mDefaultWidth = dp2px(100);
private int mDefaultHeight =mDefaultWidth;
private float mCirclRingRoateAle=0;
private ValueAnimator mValueAnimator;
public JiondongView(Context context) {
super(context);
init(context,null,0);
}
public JiondongView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context,attrs,0);
}
public JiondongView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs,defStyleAttr);
}
private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr){
mValueAnimator = ValueAnimator.ofFloat(0,1f);
mValueAnimator.setDuration(380);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCirclRingRoateAle=360*((Float)valueAnimator.getAnimatedValue());
Log.e("loadingviw","loading");
invalidate();
}
});
mValueAnimator.setRepeatCount(10000);
mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
mValueAnimator.setInterpolator(new LinearInterpolator());
//屏幕密度缩放比例
mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
//背景
mBackgroundPaint = new Paint();
mBackgroundPaint.setAntiAlias(true);
mBackgroundPaint.setDither(true);
mBackgroundPaint.setStyle(Paint.Style.FILL);
mBackgroundPaint.setColor(Color.parseColor("#bb2A2A2A"));
//圆
mCirclPaint = new Paint();
mCirclPaint.setAntiAlias(true);
mCirclPaint.setDither(true);
mCirclPaint.setStyle(Paint.Style.FILL);
mCirclPaint.setColor(Color.parseColor("#ffffff"));
//环
mCirclRingPaint = new Paint();
mCirclRingPaint.setAntiAlias(true);
mCirclRingPaint.setDither(true);
mCirclRingPaint.setStyle(Paint.Style.STROKE);
mCirclRingPaint.setStrokeWidth(2.6f*mScaledDensity);
mCirclRingPaint.setColor(Color.parseColor("#ffcc00"));
mBgWidth = (int) (60*mScaledDensity);
mBgHeight = (int) (60*mScaledDensity);
mBgRx= (int) (8*mScaledDensity);
mBgRy= (int) (8*mScaledDensity);
flag= (int) (16*mScaledDensity);
mTextdPaint = new Paint();
mTextdPaint.setAntiAlias(true);
mTextdPaint.setDither(true);
mTextdPaint.setTextSize(20*mScaledDensity);
mTextdPaint.setStyle(Paint.Style.STROKE);
mTextdPaint.setColor(Color.parseColor("#000000"));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//测量计算宽度
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthSpecMode == MeasureSpec.EXACTLY) {
//当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
mMeasureWidth = widthSpecSize;
} else {
//指定默认大小
mMeasureWidth = mDefaultWidth;
if (widthSpecMode == MeasureSpec.AT_MOST) {
mMeasureWidth = Math.min(mMeasureWidth, widthSpecSize);
}
}
//测量计算View的高
int heightSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(widthMeasureSpec);
if (heightSpecMode == MeasureSpec.EXACTLY) {
//当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
mMeasureHeight = heightSpecSize;
} else {
//指定默认大小
mMeasureHeight = mDefaultHeight;
if (heightSpecMode == MeasureSpec.AT_MOST) {
mMeasureHeight = Math.min(mMeasureHeight, heightSpecSize);
}
}
mMeasureHeight=mMeasureHeight-getPaddingBottom()-getPaddingTop();
mMeasureWidth=mMeasureWidth-getPaddingLeft()-getPaddingBottom();
//重新测量
setMeasuredDimension(mMeasureWidth, mMeasureHeight);
}
//onSizeChanged() 在控件大小发生改变时调用。所以这里初始化会被调用一次
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBgRectF = new RectF( -mBgWidth / 2, - mBgHeight / 2, mBgWidth/2, mBgHeight/2);
mMsgTextLength = mTextdPaint.measureText(mMsgText);
//文字的y轴坐标
Paint.FontMetrics fontMetrics = mTextdPaint.getFontMetrics();
mMsgTextHeight = (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2;
int[] mMinColors = {Color.YELLOW, Color.GREEN, Color.WHITE, Color.YELLOW};
//先创建一个渲染器
SweepGradient mSweepGradient = new SweepGradient(0,
0, //以圆弧中心作为扫描渲染的中心以便实现需要的效果
mMinColors, //这是我定义好的颜色数组,包含2个颜色:#35C3D7、#2894DD
null);
//把渐变设置到笔刷
mCirclRingPaint.setShader(mSweepGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(mMeasureWidth/2,mMeasureHeight/2);
if (mBgRectF != null) {
canvas.drawRoundRect(mBgRectF,mBgRx,mBgRy,mBackgroundPaint);
}
canvas.drawCircle(0,0,mBgWidth*0.4f,mCirclPaint);
canvas.drawText(mMsgText,-mMsgTextLength/2,mMsgTextHeight,mTextdPaint);
canvas.rotate(mCirclRingRoateAle);
canvas.drawCircle(0,0,mBgWidth*0.34f,mCirclRingPaint);
}
//将设置的db转为屏幕像素
protected int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
public void start(){
mValueAnimator.start();
}
public void close(){
if (mValueAnimator != null) {
mValueAnimator.cancel();
}
}
public boolean isStart() {
return mValueAnimator.isRunning();
}
}
SweepGradient 颜色渲染器,用来实现颜色的过渡