packagecom.yuntong.tv.view;
importandroid.animation.ValueAnimator;
importandroid.content.Context;
importandroid.content.res.TypedArray;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.PaintFlagsDrawFilter;
import android.graphics.RectF;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.text.TextUtils;
importandroid.util.AttributeSet;
importandroid.view.View;
importandroid.view.animation.AccelerateDecelerateInterpolator;
importandroid.view.animation.LinearInterpolator;
importcom.yuntong.tv.R;
/**
* Created by ctdw on 2017/1/10.
*/
public classYiBiaoPanViewNewextendsView {
privateContextcontext;
//刻度的结束位置
private intendDst;
//刻度的开始位置
private intstartDst;
//外环图片
privateBitmapmBitmapOutRing;
//光标图片
privateBitmapmBitmapGuangBiao;
//外环底部图片
privateBitmapmBitmapOutDoor;
//当前的刻度
private intmPerent;
//View的宽
private intmWidth;
//View的高
private intmHeight;
//总刻度的颜色
private inttotalKeDuColor;
//当前刻度的颜色
private intcurrentKeDuColor;
//最外层图片圆环和底部图片的画笔宽度
private intoutPaintWidth;
//画刻度的画笔宽度
private intkeduPaintWidth;
privatePaintFlagsDrawFiltermPaintFlagsDrawFilter;
//外层圆环和底部图片画笔
privatePaintmBitmapOutRingAndOutDoorPaint;
//总刻度的画笔
privatePaintmTotalKeduPaint;
//当前刻度的画笔
privatePaintmCurrentKeduPaint;
//最外层圆环图片的矩阵
privateRectFmBitmapOutRingRectf;
//底部图片的矩阵
privateRectFmBitmapOutDoorRecft;
private intmBitmapOutRingWidth;
private intmBitmapOutRingHeight;
private intmBitmapOutDoorWidth;
private intmBitmapOutDoorHeight;
//文本的画笔
privatePaintmCenterTextPaint;
//最上层文本的颜色
private static final intWHITE_COLOR= Color.parseColor("#ffffff");
//底部文本颜色
private static final intBLACK_COLOR= Color.parseColor("#000000");
//室内PM2.5
privateStringmPmText;
privateStringmPmTextNumber;
privateStringmPmTextLevel;
privateStringmPmTextOut;
private intcurrentKeDuColorDi;
private intmMaxNum=1000;
private intmMinNum=0;
private intmMinNumOut=0;
private intmPerents=0;
privateRectFmBitmapGuangBiaoRectf;
private intmBitmapGuangBiaoWidth;
private intmBitmapGuangBiaoHeight;
private float[]pos;
private float[]tan;
privateRectFmMiddleProgressRect;
private floatmStartAngle=139f;
private floatmCurrentAngle=0f;
privatePaintmArcProgressPaint;
private floatmTotalAngle;
privatePaintmCenterTextPaints;
privatePaintmCenterTextPaints1;
privateStringmUnitPM25="";
publicYiBiaoPanViewNew(Context context) {
this(context, null);
}
publicYiBiaoPanViewNew(Context context,AttributeSet attrs) {
this(context,attrs,0);
}
private static final intDATA_CHANGED=0;
booleanisHint=true;
HandlermHandler=newHandler() {
@Override
public voidhandleMessage(Message msg) {
switch(msg.what) {
caseDATA_CHANGED:
isHint= !isHint;
postInvalidate();
break;
}
}
};
RunnablemRunnable=newRunnable() {
@Override
public voidrun() {
mHandler.postDelayed(mRunnable,1000);
Message message =newMessage();
message.what=DATA_CHANGED;
mHandler.sendMessage(message);
}
};
publicYiBiaoPanViewNew(Context context,AttributeSet attrs, intdefStyleAttr) {
super(context,attrs,defStyleAttr);
this.context= context;
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.PanelView);
totalKeDuColor= typedArray.getColor(R.styleable.PanelView_keduColor,Color.parseColor("#365275"));
// currentKeDuColor = typedArray.getColor(R.styleable.PanelView_arcColor, Color.parseColor("#14B8D4"));
outPaintWidth= typedArray.getDimensionPixelSize(R.styleable.PanelView_outPaintWidth,5);
keduPaintWidth= typedArray.getDimensionPixelSize(R.styleable.PanelView_keduPaintWidth,3);
startDst= typedArray.getDimensionPixelOffset(R.styleable.PanelView_startDst,22);
endDst= typedArray.getDimensionPixelOffset(R.styleable.PanelView_endDst,45);
//初始化画笔
init();
mHandler.post(mRunnable);
}
/**
*初始化画笔
*/
private voidinit() {
//设置图片线条的抗锯齿
mPaintFlagsDrawFilter=newPaintFlagsDrawFilter
(0,Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG);
//外层圆环和底部图片画笔
mBitmapOutRingAndOutDoorPaint=newPaint();
mBitmapOutRingAndOutDoorPaint.setStyle(Paint.Style.STROKE);
mBitmapOutRingAndOutDoorPaint.setStrokeWidth(outPaintWidth);
//总刻度的画笔
mTotalKeduPaint=newPaint();
mTotalKeduPaint.setStyle(Paint.Style.STROKE);
mTotalKeduPaint.setStrokeWidth(keduPaintWidth);
mTotalKeduPaint.setColor(totalKeDuColor);
//当前刻度的画笔
mCurrentKeduPaint=newPaint();
mCurrentKeduPaint.setStyle(Paint.Style.STROKE);
mCurrentKeduPaint.setStrokeWidth(keduPaintWidth);
//文本画笔
mCenterTextPaint=newPaint();
mCenterTextPaint.setTextAlign(Paint.Align.CENTER);
mCenterTextPaints=newPaint();
mCenterTextPaints.setTextAlign(Paint.Align.RIGHT);
mCenterTextPaints1=newPaint();
mCenterTextPaints1.setTextAlign(Paint.Align.LEFT);
mArcProgressPaint=newPaint(Paint.ANTI_ALIAS_FLAG);
mArcProgressPaint.setStrokeWidth(1);
mArcProgressPaint.setColor(Color.TRANSPARENT);
mArcProgressPaint.setStyle(Paint.Style.STROKE);
mArcProgressPaint.setStrokeCap(Paint.Cap.ROUND);
}
/**
*测量控件的宽和高
*
*@paramwidthMeasureSpec
*@paramheightMeasureSpec
*/
@Override
protected voidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) {
intwidthSize = MeasureSpec.getSize(widthMeasureSpec);
intwidthMode = MeasureSpec.getMode(widthMeasureSpec);
intheightSize = MeasureSpec.getSize(heightMeasureSpec);
intheightMode = MeasureSpec.getMode(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY) {
mWidth= widthSize;
}else{
mWidth=477;
}
if(heightMode == MeasureSpec.EXACTLY) {
mHeight= heightSize;
}else{
mHeight=477;
}
setMeasuredDimension(mWidth,mHeight);
}
@Override
protected voidonDraw(Canvas canvas) {
//设置画布绘图无锯齿
canvas.setDrawFilter(mPaintFlagsDrawFilter);
//画圆环和底部图片
drawBitmapOutRingAndDoor(canvas);
//画文本文字
drawCenterText(canvas);
//画总刻度
drawTotalKedu(canvas);
//画当前刻度
drawCurrentKedu(canvas);
drawGuangBiao(canvas);
}
/**
*画文本文字
*
*@paramcanvas
*/
private voiddrawCenterText(Canvas canvas) {
//绘制最上边文本
mCenterTextPaint.setTextSize(36);
mCenterTextPaint.setColor(WHITE_COLOR);
canvas.drawText(mPmText,mWidth/2,outPaintWidth+114,mCenterTextPaint);
String mMinNums =mMinNum+"";
//绘制中间文本
mCenterTextPaints.setTextSize(120);
mCenterTextPaints.setColor(WHITE_COLOR);
mCenterTextPaints1.setTextSize(40);
mCenterTextPaints1.setColor(WHITE_COLOR);
intnum;
intdanwei;
if(mMinNums.length() ==4){
mCenterTextPaints.setTextSize(100);
num =40;
danwei =50;
}else{
num =30;
danwei =50;
}
canvas.drawText(mPmTextNumber,mWidth/2+ num,outPaintWidth+250,mCenterTextPaints);
canvas.drawText(mUnitPM25,mWidth/2+ danwei,outPaintWidth+250,mCenterTextPaints1);
//绘制下边文本
mCenterTextPaint.setTextSize(35);
mCenterTextPaint.setColor(WHITE_COLOR);
canvas.drawText(mPmTextLevel,mWidth/2,mHeight-88-outPaintWidth,mCenterTextPaint);
mCenterTextPaint.setTextSize(40);
mCenterTextPaint.setColor(WHITE_COLOR);
canvas.drawText(mPmTextOut,mWidth/2,mHeight-18,mCenterTextPaint);
}
/**
*画当前刻度
*
*@paramcanvas
*/
private voiddrawCurrentKedu(Canvas canvas) {
mCurrentKeduPaint.setColor(currentKeDuColor);
if(mPerent==0) {
//旋转画布
canvas.save();
canvas.rotate(-139f,mWidth/2,mWidth/2);
//旋转的角度
floatrAngle = (280.9f/100);
for(inti =1;i <=0;i++) {
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mCurrentKeduPaint);
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
canvas.restore();
}else if(mPerent==100) {
//旋转画布
canvas.save();
//旋转的角度
floatrAngle = (280.9f/100);
canvas.rotate(-139,mWidth/2,mWidth/2);
for(inti =1;i <=100;i++) {
if(i ==100) {
if(isHint) {
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mCurrentKeduPaint);
}
}
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
canvas.restore();
//旋转画布
canvas.save();
//旋转的角度
floatrAngles = (280.9f/100);
canvas.rotate(-139,mWidth/2,mWidth/2);
for(inti =1;i <100;i++) {
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mCurrentKeduPaint);
canvas.rotate(rAngles,mWidth/2,mWidth/2);
}
canvas.restore();
}else{
//旋转画布
canvas.save();
//旋转的角度
floatrAngle = (280.9f/100);
canvas.rotate(-139,mWidth/2,mWidth/2);
for(inti =1;i <=mPerents;i++) {
if(i ==mPerents) {
if(isHint) {
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mCurrentKeduPaint);
}
}
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
canvas.restore();
//旋转画布
canvas.save();
//旋转的角度
floatrAngles = (280.9f/100);
canvas.rotate(-139,mWidth/2,mWidth/2);
for(inti =1;i
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mCurrentKeduPaint);
canvas.rotate(rAngles,mWidth/2,mWidth/2);
}
canvas.restore();
}
}
private voiddrawGuangBiao(Canvas canvas) {
mCurrentKeduPaint.setColor(currentKeDuColor);
//光标的矩阵
mBitmapGuangBiaoRectf=newRectF((mWidth-mBitmapGuangBiaoWidth) /2,outPaintWidth/2+ dp2px(3f),(mWidth-mBitmapGuangBiaoWidth) /2+mBitmapGuangBiaoWidth,outPaintWidth/2+ dp2px(3f) +mBitmapGuangBiaoHeight);
if(mPerents==0) {
//旋转画布
canvas.save();
canvas.rotate(-139f,mWidth/2,mWidth/2);
//旋转的角度
floatrAngle = (280.9f/100);
for(inti =1;i <=0;i++) {
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
if(isHint) {
canvas.drawBitmap(mBitmapGuangBiao, null,mBitmapGuangBiaoRectf,mCurrentKeduPaint);
}
canvas.restore();
}else if(mPerents==100) {
//旋转画布
canvas.save();
canvas.rotate(-139f,mWidth/2,mWidth/2);
//旋转的角度
floatrAngle = (280.9f/100);
for(inti =2;i <=mPerents;i++) {
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
if(isHint) {
canvas.drawBitmap(mBitmapGuangBiao, null,mBitmapGuangBiaoRectf,mCurrentKeduPaint);
}
canvas.restore();
}else{
//旋转画布
canvas.save();
//旋转的角度
floatrAngle = (280.9f/100);
canvas.rotate(-139,mWidth/2,mWidth/2);
for(inti =2;i <=mPerents;i++) {
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
if(isHint) {
canvas.drawBitmap(mBitmapGuangBiao, null,mBitmapGuangBiaoRectf,mCurrentKeduPaint);
}
canvas.restore();
}
}
/**
*画总刻度
*
*@paramcanvas
*/
private voiddrawTotalKedu(Canvas canvas) {
canvas.save();
canvas.rotate(139f,mWidth/2,mWidth/2);
//旋转的角度
floatrAngle = -280.9f/100;
for(inti =1;i <=100;i++) {
canvas.drawLine(mWidth/2,startDst,mWidth/2,endDst,mTotalKeduPaint);
canvas.rotate(rAngle,mWidth/2,mWidth/2);
}
canvas.restore();
}
/**
*画圆环和底部图片
*
*@paramcanvas
*/
private voiddrawBitmapOutRingAndDoor(Canvas canvas) {
mBitmapOutRingAndOutDoorPaint.setColor(currentKeDuColorDi);
//最外层圆环图片的矩阵
mBitmapOutRingRectf=newRectF(outPaintWidth/2,outPaintWidth/2,mWidth-outPaintWidth/2,mHeight-outPaintWidth/2);
//底部图片的矩阵
mBitmapOutDoorRecft=newRectF((mWidth-mBitmapOutDoorWidth-outPaintWidth) /2+3,mHeight-mBitmapOutDoorHeight-outPaintWidth/2+2,(mWidth-mBitmapOutDoorWidth) /2+mBitmapOutDoorWidth+outPaintWidth/2-2,mHeight);
canvas.drawBitmap(mBitmapOutDoor, null,mBitmapOutDoorRecft,mBitmapOutRingAndOutDoorPaint);
mBitmapOutRingAndOutDoorPaint.setColor(currentKeDuColor);
canvas.drawBitmap(mBitmapOutRing, null,mBitmapOutRingRectf,mBitmapOutRingAndOutDoorPaint);
}
/**
*设置当前PM25的值
*@paramnumber
*@paramnumOut
*@paramvalues
*@parami
*@paramunitPM25
*/
public voidsetCurrentPM25Values(intnumber,String numOut,String values, inti,String unitPM25) {
intnumberOut;
if(TextUtils.equals("",numOut)) {
numberOut =0;
}else{
numberOut = Integer.parseInt(numOut);
}
if(i <=35&& i >=0) {
//空气质量优
mPerent= number;
mPmTextLevel="空气质量优";
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree1);
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon1);
currentKeDuColor= Color.parseColor("#5dca7e");
currentKeDuColorDi= Color.parseColor("#5dca7e");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg1);
}else if(i >35&& i <=75) {
//空气质量良
mPmTextLevel="空气质量良";
mPerent= number;
currentKeDuColor= Color.parseColor("#a6d062");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon2);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree2);
currentKeDuColorDi= Color.parseColor("#a6d062");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg2);
}else if(i >75&& i <=115) {
//轻度污染
mPerent= number;
mPmTextLevel="轻度污染";
currentKeDuColor= Color.parseColor("#f9cf61");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon3);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree3);
currentKeDuColorDi= Color.parseColor("#f9cf61");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg3);
}else if(i >115&& i <=150) {
//中度污染
mPerent= number;
mPmTextLevel="中度污染";
currentKeDuColor= Color.parseColor("#fcb161");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon4);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree4);
currentKeDuColorDi= Color.parseColor("#fcb161");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg4);
}else if(i >150&& i <=250) {
//重度污染
mPerent= number;
mPmTextLevel="重度污染";
mTotalAngle= number *280.9f/100;
currentKeDuColor= Color.parseColor("#ef855b");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon5);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree5);
currentKeDuColorDi= Color.parseColor("#ef855b");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg5);
}else if(i >250&& i <=1000) {
//严重污染
mPerent= number;
mPmTextLevel="严重污染";
mTotalAngle=280.9f;
currentKeDuColor= Color.parseColor("#ed6160");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon6);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree6);
currentKeDuColorDi= Color.parseColor("#ed6160");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg6);
}else{
//严重污染
mPerent=100;
mPmTextLevel="严重污染";
mTotalAngle=280.9f;
currentKeDuColor= Color.parseColor("#ed6160");
mBitmapGuangBiao= BitmapFactory.decodeResource(getResources(),R.drawable.cursor_icon6);
mBitmapOutRing= BitmapFactory.decodeResource(getResources(),R.drawable.pollution_degree6);
currentKeDuColorDi= Color.parseColor("#ed6160");
mBitmapOutDoor= BitmapFactory.decodeResource(getResources(),R.drawable.outdoor_data_bg6);
}
this.mUnitPM25= unitPM25;
mPmText="室内PM2.5";
mPmTextNumber= values;
mPmTextOut="室外:"+ numOut;
mBitmapOutRingWidth=mBitmapOutRing.getWidth();
mBitmapOutRingHeight=mBitmapOutRing.getHeight();
mBitmapGuangBiaoWidth=px2dip(context,mBitmapGuangBiao.getWidth());
mBitmapGuangBiaoHeight=px2dip(context,mBitmapGuangBiao.getHeight());
mBitmapOutDoorWidth=px2dip(context,mBitmapOutDoor.getWidth());
mBitmapOutDoorHeight=px2dip(context,mBitmapOutDoor.getHeight());
startRotateAnim(number,values,numOut,mTotalAngle);
}
/**
*开始刻度绘制动画和数字的改变 和文字的改变
*/
private voidstartRotateAnim(intnum,String values,String numOut, floattotalAngle) {
ValueAnimator mAngleAnim = ValueAnimator.ofFloat(mCurrentAngle,totalAngle);
mAngleAnim.setInterpolator(newAccelerateDecelerateInterpolator());
mAngleAnim.setDuration(2000);
mAngleAnim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator valueAnimator) {
mCurrentAngle= (float) valueAnimator.getAnimatedValue();
postInvalidate();
}
});
mAngleAnim.start();
ValueAnimator keduAnim = ValueAnimator.ofInt(mPerents,num);
keduAnim.setInterpolator(newAccelerateDecelerateInterpolator());
keduAnim.setDuration(2000);
keduAnim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator animation) {
mPerents= (int) animation.getAnimatedValue();
postInvalidate();
}
});
keduAnim.start();
ValueAnimator mNumAnim = ValueAnimator.ofInt(mMinNum,Integer.parseInt(values));
mNumAnim.setDuration(2000);
mNumAnim.setInterpolator(newLinearInterpolator());
mNumAnim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator valueAnimator) {
mMinNum= (int) valueAnimator.getAnimatedValue();
postInvalidate();
}
});
mNumAnim.start();
ValueAnimator mNumAnimOut = ValueAnimator.ofInt(mMinNumOut,Integer.parseInt(numOut));
mNumAnimOut.setDuration(2000);
mNumAnimOut.setInterpolator(newLinearInterpolator());
mNumAnimOut.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator valueAnimator) {
mMinNumOut= (int) valueAnimator.getAnimatedValue();
postInvalidate();
}
});
mNumAnimOut.start();
}
/**
* dp2px
*/
public intdp2px(floatvalues) {
floatdensity = getResources().getDisplayMetrics().density;
return(int) (values * density +0.5f);
}
public static intpx2dip(Context context, intpxValue) {
floatscale = context.getResources().getDisplayMetrics().density;
return(int) (pxValue / scale +0.5f);
}
}
附上自定义属性
最后附上效果图: