package com.moral.yunfushao.ui;
|
|
import android.animation.ValueAnimator;
|
import android.content.Context;
|
import android.content.res.Resources;
|
import android.graphics.Bitmap;
|
import android.graphics.Canvas;
|
import android.graphics.Color;
|
import android.graphics.Paint;
|
import android.graphics.RectF;
|
import android.graphics.SweepGradient;
|
import android.graphics.drawable.BitmapDrawable;
|
import android.support.annotation.Nullable;
|
import android.util.AttributeSet;
|
import android.util.TypedValue;
|
import android.view.View;
|
|
import com.moral.yunfushao.R;
|
|
/**
|
* 轮盘
|
* Created by haijiang on 2017/6/20.
|
*/
|
|
public class PanelView extends View {
|
private Context mContext;
|
private int mWidth;
|
private int mmWidth;
|
private int mmHeight;
|
//绘制渐变圆弧的画笔
|
private Paint mShaderPaint;
|
private int[] mshaderColor = new int[]{0xfff70e17, 0xfff70e17, 0xfff70e17, 0xffff5c92, 0xff00c44a, 0xff00d062, 0xff00f5af, 0xff00f6cb, 0xff00ccff, 0xff179fff, 0xffa054ff, 0xffa53aff, 0xffd74bff, 0xfff64da5, 0xfff70e17};
|
private int[] mshaderRedColor = new int[]{0xfff70e17, 0xffff5c92};
|
private int[] mshaderZiseColor = new int[]{0xffa53aff, 0xffd74bff, 0xfff64da5};
|
private int[] mshaderBlueColor = new int[]{0xff00f6cb, 0xff00ccff, 0xff179fff, 0xffa054ff};
|
private int[] mshaderGreenColor = new int[]{0xff00c44a, 0xff00d062, 0xff00f5af};
|
//环形渐变色值渲染
|
private SweepGradient mSweepGradient;
|
private int mShaderWidth = 70;
|
//画圆环上的线
|
private Paint paintGapLine;
|
|
//小格子线颜色3°画一次
|
private int line1Color = 0xffb8e8f4;
|
//小格子线颜色15°画一次
|
private int line2Color = 0xff7ed3ff;
|
//小格子线颜色60°画一次
|
private int line3Color = 0xff009cff;
|
//短线长度
|
private int line1Length = 50;
|
//长线长度
|
private int line2Length = 70;
|
private int lineWidth = 6;
|
//内外间隔
|
private int widthInner = 120;
|
private int paddingKedu = 40;
|
private Paint mLinePaint;
|
|
//画刻度文字
|
private Paint drawTextPaint;
|
private int textColor = Color.GRAY;
|
private int textSize = 36;
|
private String[] level = {"安全状态", "建议回避", "及时闪躲", "紧急撤离"};
|
|
//内进度圆
|
private Paint mCirclePaint;
|
private int innerCircleColor = 0xffb8e8f4;
|
private int mCircleWidth = 70;
|
private int innerPadding = 20;
|
//画进度
|
private Paint mProgressPaint;
|
private int progressCircleColor = 0xff53c9ff;
|
|
//画指针
|
private Paint mBitPaint;
|
private Bitmap mBitmap;
|
|
private float percent = 0;//百分比数据
|
private float percent2 = (float) 0.27;//百分比数据
|
|
|
private String statusStr = "未连接";
|
private ValueAnimator anim;
|
|
public void setStatusStr(String statusStr) {
|
this.statusStr = statusStr;
|
postInvalidate();
|
}
|
|
public void setPercent(float percent) {
|
this.percent = percent;
|
// this.percent2 = percent;
|
postInvalidate();
|
// if (anim.isStarted() || anim.isRunning()) {
|
// anim.end();
|
// anim.cancel();
|
// }
|
// anim.start();
|
}
|
|
public PanelView(Context context) {
|
super(context);
|
init(context);
|
}
|
|
public PanelView(Context context, @Nullable AttributeSet attrs) {
|
super(context, attrs);
|
init(context);
|
}
|
|
public PanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
super(context, attrs, defStyleAttr);
|
init(context);
|
}
|
|
private void init(Context mContext) {
|
this.mContext = mContext;
|
//初始化
|
mShaderWidth = dip2px(mContext, 24);
|
line1Length = dip2px(mContext, 14);
|
line2Length = dip2px(mContext, 22);
|
lineWidth = dip2px(mContext, 2);
|
widthInner = dip2px(mContext, 40);
|
paddingKedu = dip2px(mContext, 10);
|
mCircleWidth = dip2px(mContext, 24);
|
innerPadding = dip2px(mContext, 8);
|
textSize = dip2px(mContext, 12);
|
|
//渐变圆环
|
mShaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
mShaderPaint.setStyle(Paint.Style.STROKE);
|
mShaderPaint.setStrokeWidth(mShaderWidth);
|
mShaderPaint.setStrokeCap(Paint.Cap.ROUND);
|
paintGapLine = new Paint(Paint.ANTI_ALIAS_FLAG);
|
paintGapLine.setColor(Color.WHITE);
|
paintGapLine.setStrokeWidth(dip2px(mContext, 3));
|
//刻度
|
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
mLinePaint.setStyle(Paint.Style.STROKE);
|
mLinePaint.setStrokeWidth(lineWidth);
|
mLinePaint.setColor(line1Color);
|
//文字
|
drawTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
drawTextPaint.setColor(textColor);
|
drawTextPaint.setTextSize(textSize);
|
//内进度圆
|
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
mCirclePaint.setStyle(Paint.Style.STROKE);
|
mCirclePaint.setStrokeWidth(mCircleWidth);
|
mCirclePaint.setStrokeCap(Paint.Cap.ROUND);
|
mCirclePaint.setColor(innerCircleColor);
|
//画进度
|
mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
mProgressPaint.setStyle(Paint.Style.STROKE);
|
mProgressPaint.setStrokeWidth(mCircleWidth);
|
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
|
mProgressPaint.setColor(progressCircleColor);
|
//画指针
|
mBitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
mBitPaint.setFilterBitmap(true);
|
mBitPaint.setDither(true);
|
mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.mipmap.zhizhen)).getBitmap();
|
// startAnimation();
|
}
|
|
@Override
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
if (widthMode == MeasureSpec.EXACTLY) {
|
mmWidth = widthSize;
|
} else {
|
mmWidth = dip2px(mContext, 300);
|
}
|
if (heightMode == MeasureSpec.EXACTLY) {
|
mmHeight = heightSize;
|
} else {
|
mmHeight = dip2px(mContext, 300);
|
}
|
mWidth = mmWidth < mmHeight ? mmWidth : mmHeight;
|
setMeasuredDimension(mmWidth, mmHeight);
|
}
|
|
// private void startAnimation() {
|
// anim = ValueAnimator.ofObject(new CustomPointEvaluator(),(float)0, percent2);
|
// anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
// @Override
|
// public void onAnimationUpdate(ValueAnimator animation) {
|
// percent = (float) animation.getAnimatedValue();
|
// System.out.println("chenqi rotato " + percent + " all -> " + percent2 * 300);
|
//// invalidate();
|
// }
|
// });
|
// anim.setDuration(3000L);
|
// anim.setRepeatCount(Animation.INFINITE);
|
// }
|
//
|
// private class CustomPointEvaluator implements TypeEvaluator<Float> {
|
// @Override
|
// public Float evaluate(float fraction, Float startValue, Float endValue) {
|
// System.out.println("chenqi2 rotato " + fraction + " all -> " + endValue);
|
// float y = fraction * endValue;
|
// return y;
|
// }
|
// }
|
|
|
@Override
|
protected void onDraw(Canvas canvas) {
|
super.onDraw(canvas);
|
//画刻度
|
drawKedu(canvas);
|
//画刻度文字
|
drawTextKedu(canvas);
|
//画渐变圆环
|
drawJianbianCircle(canvas);
|
//画内圆
|
RectF cirlcleRect = new RectF(mShaderWidth + widthInner + mCircleWidth + innerPadding, mShaderWidth + widthInner + mCircleWidth + innerPadding, mWidth - mShaderWidth - widthInner - mCircleWidth - innerPadding, mWidth - mShaderWidth - widthInner - mCircleWidth - innerPadding);
|
canvas.drawArc(cirlcleRect, 0, 360, false, mCirclePaint);
|
//画指针
|
float circleR = (cirlcleRect.right - cirlcleRect.left) / 2;
|
float bitH = circleR;
|
float bitW = bitH * 0.448f;
|
canvas.save();
|
canvas.rotate(percent * 300 - 150, mWidth / 2, mWidth / 2);
|
RectF btmRect = new RectF((float) (cirlcleRect.left + bitH - bitW * 0.535), (float) (cirlcleRect.top + mCircleWidth * 0.68), (float) (cirlcleRect.left + bitH + bitW * 0.465), (float) (cirlcleRect.top + bitH + mCircleWidth * 0.68));
|
// Log.d("haijiang","left="+btmRect.left);
|
// Log.d("haijiang","right="+btmRect.right);
|
// Log.d("haijiang","top="+btmRect.top);
|
// Log.d("haijiang","bottom="+btmRect.bottom);
|
// Log.d("haijiang","宽高比例="+(btmRect.right-btmRect.left)/(btmRect.bottom-btmRect.top));
|
canvas.drawBitmap(mBitmap, null, btmRect, mBitPaint);
|
canvas.restore();
|
|
drawTextPaint.setColor(line3Color);
|
drawTextPaint.setTextSize(textSize);
|
int statusStrWidth = (int) drawTextPaint.measureText(this.statusStr);
|
canvas.drawText(this.statusStr, mWidth / 2 - statusStrWidth / 2, mWidth / 2 + (btmRect.bottom - btmRect.top) / 2, drawTextPaint);
|
if (percent > 0)
|
canvas.drawArc(new RectF(mShaderWidth + widthInner + mCircleWidth + innerPadding, mShaderWidth + widthInner + mCircleWidth + innerPadding, mWidth - mShaderWidth - widthInner - mCircleWidth - innerPadding, mWidth - mShaderWidth - widthInner - mCircleWidth - innerPadding),
|
120, 300 * percent, false, mProgressPaint);
|
}
|
|
/**
|
* 画刻度
|
*
|
* @param canvas
|
*/
|
private void drawKedu(Canvas canvas) {
|
//画右边刻度
|
for (int i = 0; i <= 50; i++) {
|
canvas.save();
|
if (i % 5 == 0) {
|
mLinePaint.setColor(line2Color);
|
canvas.rotate(i * 3, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, paddingKedu, mWidth / 2, line2Length + paddingKedu, mLinePaint);
|
} else {
|
mLinePaint.setColor(line1Color);
|
canvas.rotate(i * 3, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, paddingKedu, mWidth / 2, line1Length + paddingKedu, mLinePaint);
|
}
|
canvas.restore();
|
}
|
//画右边刻度
|
for (int j = 0; j <= 50; j++) {
|
canvas.save();
|
if (j % 5 == 0) {
|
mLinePaint.setColor(line2Color);
|
canvas.rotate(-j * 3, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, paddingKedu, mWidth / 2, line2Length + paddingKedu, mLinePaint);
|
} else {
|
mLinePaint.setColor(line1Color);
|
canvas.rotate(-j * 3, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, paddingKedu, mWidth / 2, line1Length + paddingKedu, mLinePaint);
|
}
|
canvas.restore();
|
}
|
}
|
|
/**
|
* 画刻度文字
|
*
|
* @param canvas
|
*/
|
private void drawTextKedu(Canvas canvas) {
|
for (int i = 0; i < level.length; i++) {
|
float textWidth = drawTextPaint.measureText(level[i]);
|
if (percent < 0.25) {
|
if (i == 0) {
|
drawTextPaint.setColor(line3Color);
|
} else {
|
drawTextPaint.setColor(Color.GRAY);
|
}
|
canvas.save();
|
if (i == 0) {
|
canvas.rotate(-120, mWidth / 2, mWidth / 2);
|
} else if (i == 1) {
|
canvas.rotate(-45, mWidth / 2, mWidth / 2);
|
} else if (i == 2) {
|
canvas.rotate(45, mWidth / 2, mWidth / 2);
|
} else if (i == 3) {
|
canvas.rotate(120, mWidth / 2, mWidth / 2);
|
}
|
canvas.drawText(level[i], mWidth / 2 - textWidth / 2, paddingKedu + line2Length + textSize, drawTextPaint);
|
canvas.restore();
|
} else if (percent >= 0.25 && percent < 0.5) {
|
if (i == 1) {
|
drawTextPaint.setColor(line3Color);
|
} else {
|
drawTextPaint.setColor(Color.GRAY);
|
}
|
canvas.save();
|
// canvas.rotate(-120+i*75,mWidth/2,mWidth/2);
|
if (i == 0) {
|
canvas.rotate(-120, mWidth / 2, mWidth / 2);
|
} else if (i == 1) {
|
canvas.rotate(-45, mWidth / 2, mWidth / 2);
|
} else if (i == 2) {
|
canvas.rotate(45, mWidth / 2, mWidth / 2);
|
} else if (i == 3) {
|
canvas.rotate(120, mWidth / 2, mWidth / 2);
|
}
|
canvas.drawText(level[i], mWidth / 2 - textWidth / 2, paddingKedu + line2Length + textSize, drawTextPaint);
|
canvas.restore();
|
} else if (percent >= 0.5 && percent < 0.75) {
|
if (i == 2) {
|
drawTextPaint.setColor(line3Color);
|
} else {
|
drawTextPaint.setColor(Color.GRAY);
|
}
|
canvas.save();
|
// canvas.rotate(-120+i*75,mWidth/2,mWidth/2);
|
if (i == 0) {
|
canvas.rotate(-120, mWidth / 2, mWidth / 2);
|
} else if (i == 1) {
|
canvas.rotate(-45, mWidth / 2, mWidth / 2);
|
} else if (i == 2) {
|
canvas.rotate(45, mWidth / 2, mWidth / 2);
|
} else if (i == 3) {
|
canvas.rotate(120, mWidth / 2, mWidth / 2);
|
}
|
canvas.drawText(level[i], mWidth / 2 - textWidth / 2, paddingKedu + line2Length + textSize, drawTextPaint);
|
canvas.restore();
|
} else if (percent >= 0.75) {
|
if (i == 3) {
|
drawTextPaint.setColor(line3Color);
|
} else {
|
drawTextPaint.setColor(Color.GRAY);
|
}
|
canvas.save();
|
// canvas.rotate(-105+i*75,mWidth/2,mWidth/2);
|
if (i == 0) {
|
canvas.rotate(-120, mWidth / 2, mWidth / 2);
|
} else if (i == 1) {
|
canvas.rotate(-45, mWidth / 2, mWidth / 2);
|
} else if (i == 2) {
|
canvas.rotate(45, mWidth / 2, mWidth / 2);
|
} else if (i == 3) {
|
canvas.rotate(120, mWidth / 2, mWidth / 2);
|
}
|
canvas.drawText(level[i], mWidth / 2 - textWidth / 2, paddingKedu + line2Length + textSize, drawTextPaint);
|
canvas.restore();
|
}
|
}
|
}
|
|
/**
|
* 画渐变圆环
|
*
|
* @param canvas
|
*/
|
private void drawJianbianCircle(Canvas canvas) {
|
mSweepGradient = new SweepGradient(mWidth / 2, mWidth / 2, mshaderColor, null);
|
mShaderPaint.setShader(mSweepGradient);
|
canvas.drawArc(new RectF(mShaderWidth + widthInner, mShaderWidth + widthInner, mWidth - mShaderWidth - widthInner, mWidth - mShaderWidth - widthInner), 120, 300, false, mShaderPaint);
|
//画圆环分隔
|
canvas.save();
|
canvas.rotate(75, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, line2Length + paddingKedu * 3, mWidth / 2, (float) (line2Length + paddingKedu * 0.65 + mShaderWidth * 2), paintGapLine);
|
canvas.restore();
|
canvas.save();
|
canvas.rotate(0, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, line2Length + paddingKedu * 3, mWidth / 2, (float) (line2Length + paddingKedu * 0.65 + mShaderWidth * 2), paintGapLine);
|
canvas.restore();
|
canvas.save();
|
canvas.rotate(-75, mWidth / 2, mWidth / 2);
|
canvas.drawLine(mWidth / 2, line2Length + paddingKedu * 3, mWidth / 2, (float) (line2Length + paddingKedu * 0.65 + mShaderWidth * 2), paintGapLine);
|
canvas.restore();
|
}
|
|
|
/**
|
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
*/
|
public static int dip2px(Context context, float dpValue) {
|
Resources r = context.getResources();
|
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
dpValue, r.getDisplayMetrics());
|
return (int) px;
|
}
|
|
/**
|
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
*/
|
public static int px2dip(Context context, float pxValue) {
|
final float scale = context.getResources().getDisplayMetrics().density;
|
return (int) (pxValue / scale + 0.5f);
|
}
|
|
/**
|
* 根据手机的分辨率从 px(像素) 的单位 转成为 sp
|
*/
|
public static int px2sp(Context context, float pxValue) {
|
float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
|
return (int) (pxValue / fontScale + 0.5f);
|
}
|
|
/**
|
* 根据手机的分辨率从 sp 的单位 转成为 px
|
*/
|
public static int sp2px(Context context, float spValue) {
|
float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
|
return (int) (spValue * fontScale + 0.5f);
|
}
|
}
|