Android绘制学习——基础形状
来源:互联网 发布:移动网络ip地址是什么 编辑:程序博客网 时间:2024/06/05 05:58
有些地方待优化处理,这里就没做处理,只是用来学习记录
public class BarChartView extends View { private Context context; // 画布的位置 private int XPoint; private int YPoint; //刻度长度 private int XScale = 100; private int YScale = 60; // x轴y轴的线长 private int XLength; private int YLength; // 要减去箭头的长度 // 顶部 底部文字的高度 private int topTextHight = 60; private int bottomTextHight = 100; // 设置柱状的高度 private int height = (int)dipToPx(20); private float betweenHeight; // 选中的id private int chooseId = -1; private int MaxDataSize = XLength / XScale; private int[] mColors; //对象的颜色 private List<String> text = new ArrayList<>(); // 底部标题 private List<RunStatusBean> infos = new ArrayList<>(); // 每个横条的信息 // 初始化画笔 private Paint paint; private Paint YPaint; private Paint YArrowsPaint; private Paint headPaint; private Paint dottedPaint; private Paint datePaint; private Paint rectanglePaint; private Paint textInRectangle; private Paint bottomLinePaint; private Paint bottomDiscripPain; public BarChartView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; // 初始化每一个级别的颜色 mColors = new int[]{Color.parseColor("#F47564"),Color.parseColor("#F2AE6D"),Color.parseColor("#4FC3B8") ,Color.parseColor("#64AFF4")}; // 初始化画笔 paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setAntiAlias(true); paint.setColor(Color.BLUE); // y轴 YPaint = new Paint(); YPaint.setStyle(Paint.Style.STROKE); YPaint.setAntiAlias(true); YPaint.setColor(Color.parseColor("#B0B0B0")); // y轴箭头arrows YArrowsPaint = new Paint(); YArrowsPaint.setStyle(Paint.Style.STROKE); YArrowsPaint.setAntiAlias(true); YArrowsPaint.setColor(Color.parseColor("#B0B0B0")); // 头部标题 headPaint = new Paint(); headPaint.setTextSize(dipToPx(15)); headPaint.setColor(Color.parseColor("#B0B0B0")); headPaint.setAntiAlias(true); headPaint.setTextAlign(Paint.Align.CENTER); //虚线 dottedPaint = new Paint(); dottedPaint.setStyle(Paint.Style.STROKE); PathEffect effects = new DashPathEffect(new float[]{5,5,5,5},1); dottedPaint.setAntiAlias(true); dottedPaint.setPathEffect(effects); //日期文字 datePaint = new Paint(); datePaint.setAntiAlias(true); datePaint.setTextSize(20); datePaint.setTextAlign(Paint.Align.CENTER); //矩形 rectanglePaint = new Paint(); rectanglePaint.setAntiAlias(true); rectanglePaint.setStyle(Paint.Style.FILL);//充满 // 矩形中的文字 textInRectangle = new Paint(); textInRectangle.setTextSize(20); textInRectangle.setColor(Color.parseColor("#FFFFFF")); textInRectangle.setAntiAlias(true); textInRectangle.setTextAlign(Paint.Align.CENTER); //底部描述文字的矩形 bottomLinePaint = new Paint(); bottomLinePaint.setStyle(Paint.Style.STROKE); bottomLinePaint.setStrokeWidth(16); bottomLinePaint.setAntiAlias(true); // 底部的描述文字 bottomDiscripPain = new Paint(); bottomDiscripPain.setColor(Color.parseColor("#A1A6BB")); bottomDiscripPain.setAntiAlias(true); bottomDiscripPain.setTextSize(26); bottomDiscripPain.setTextAlign(Paint.Align.CENTER); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureHeight(int measureSpec) { int result = Constant.windowHeight / 3; //结果 int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.AT_MOST: // 子容器可以是声明大小内的任意大小 result = specSize; break; case MeasureSpec.EXACTLY: //父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间. 比如EditTextView中的DrawLeft result = (int)(Constant.windowHeight*(0.4)); break; case MeasureSpec.UNSPECIFIED: //父容器对于子容器没有任何限制,子容器想要多大就多大. 所以完全取决于子view的大小 result = specSize; break; } return result; } private int measureWidth(int measureSpec) { int result = Constant.windowWidth; //默认的size int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.AT_MOST: // 子容器可以是声明大小内的任意大小 result = specSize; break; case MeasureSpec.EXACTLY: //父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间. 比如EditTextView中的DrawLeft result = specSize; break; case MeasureSpec.UNSPECIFIED: //父容器对于子容器没有任何限制,子容器想要多大就多大. 所以完全取决于子view的大小 result = (text.size() + 2) * XScale; break; default: break; } return result; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画布宽高的确定 int measuredHeight = getMeasuredHeight(); int measuredWidth = getMeasuredWidth(); //起画点 YPoint = measuredHeight; XPoint = 60; // land的y坐标 landY = YPoint - 16; // y坐标长度 YLength = measuredHeight - bottomTextHight - topTextHight; XLength = measuredWidth; // y坐标刻度 YScale = YLength / 5; MaxDataSize = XLength / XScale; // 设置柱状的间距 betweenHeight = context.getResources().getDimensionPixelSize(R.dimen.y60); /*-----------------------------------------------绘制图型--------------------------------------------*/ //画Y轴 canvas.drawLine(XPoint, YPoint - bottomTextHight, XPoint, YPoint - YLength - bottomTextHight, YPaint); //Y轴箭头 canvas.drawLine(XPoint, YPoint - YLength - bottomTextHight, XPoint - 3, YPoint-YLength - bottomTextHight + 6, YPaint); canvas.drawLine(XPoint, YPoint - YLength - bottomTextHight, XPoint + 3, YPoint-YLength - bottomTextHight + 6, YPaint); //画X轴 canvas.drawLine(XPoint, YPoint - bottomTextHight, XPoint + text.size() * XScale, YPoint - bottomTextHight, YPaint); // 头标题 canvas.drawText("单位:kwh",XPoint + dipToPx(30), topTextHight - 20, headPaint); //画x轴上的虚线 if(text.size() > 1){ for(int i=0; i<text.size(); i++){ if (i == chooseId){ dottedPaint.setColor(Color.parseColor("#222328")); }else{ dottedPaint.setColor(Color.parseColor("#B0B0B0")); } Path path = new Path(); path.moveTo(XPoint + (i+1) * XScale, YPoint - bottomTextHight); path.lineTo(XPoint + (i + 1) * XScale, YPoint - YLength - bottomTextHight); canvas.drawPath(path, dottedPaint); } } // 画x轴下的文字 if(text.size() > 1){ for(int i=0; i<text.size(); i++){ if (i == chooseId){ datePaint.setColor(Color.parseColor("#0786E7")); }else{ datePaint.setColor(Color.parseColor("#B0B0B0")); } canvas.drawText(text.get(i),XPoint + (i+1) * XScale,YPoint -bottomTextHight + 40,datePaint); } } // 画矩形(主要计算出矩形的长度) for (int i =0; i<infos.size(); i++){ int heightCount = 0; // 颜色控制 if (infos.get(i).getStatus() == 0){ // 关机 rectanglePaint.setColor(mColors[0]); heightCount = 1; }if (infos.get(i).getStatus() == 10){// 正常 rectanglePaint.setColor(mColors[1]); heightCount = 2; }if (infos.get(i).getStatus() == 20){// 故障 heightCount = 3; rectanglePaint.setColor(mColors[2]); }if (infos.get(i).getStatus() == 30){// 带病运行 heightCount = 4; rectanglePaint.setColor(mColors[3]); } // 画矩形 float left = ((infos.get(i).getStart()-1) + 0.5f) * XScale + XPoint; // 拿到月份确定left的位置 和 rigth的位置() float right = left + (infos.get(i).getEnd()-infos.get(i).getStart() + 1)*XScale; float top = YPoint - bottomTextHight - heightCount * (betweenHeight) - height ; // 根据状态判断高度 float bottom = YPoint - bottomTextHight - heightCount * (betweenHeight) ; // height 为矩形的高度 RectF oval3 = new RectF(left, top, right, bottom);// 设置个新的长方形 canvas.drawRoundRect(oval3, 10, 10, rectanglePaint);//第二个参数是x半径,第三个参数是y半径 // 画文字 canvas.drawText(infos.get(i).getDesc(), (right - left) / 2 + left, height / 2 + top + 6, textInRectangle); } //画底部描述线条 bottomLinePaint.setColor(mColors[3]); canvas.drawLine(XPoint, landY, XPoint + landWidth, landY, bottomLinePaint); bottomLinePaint.setColor(mColors[2]); canvas.drawLine(XPoint + landWidth + landAmong + textWidth(landText[0],26,bottomLinePaint), landY , XPoint + (landWidth *2) + landAmong + textWidth(landText[0],26,bottomLinePaint), landY, bottomLinePaint); bottomLinePaint.setColor(mColors[1]); canvas.drawLine(XPoint + (landWidth *2) + (landAmong *2) + textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint) , landY, XPoint + (landWidth *3) + (landAmong *2)+ textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint), landY, bottomLinePaint); bottomLinePaint.setColor(mColors[0]); canvas.drawLine(XPoint + (landWidth *3) + (landAmong *3)+ 2*textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint) , landY, XPoint + (landWidth *4) + (landAmong *3)+2*textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint) , landY, bottomLinePaint); //画底部描述文字 canvas.drawText(landText[0] , excursion + XPoint + landWidth + (landAmong + textWidth(landText[0],26,bottomDiscripPain))/ 2 , landY + 8, bottomDiscripPain); canvas.drawText(landText[1] , excursion + XPoint + (landWidth * 2) + (landAmong + textWidth(landText[1],26,bottomDiscripPain))/ 2 + (landAmong + textWidth(landText[0],26,bottomDiscripPain)) ,landY + 8, bottomDiscripPain); canvas.drawText(landText[2] , excursion + XPoint + (landWidth * 3) +(landAmong + textWidth(landText[0],26,bottomDiscripPain))+(landAmong + textWidth(landText[1],26,bottomDiscripPain))+((landAmong + textWidth(landText[2],26,bottomDiscripPain))/2) ,landY +8,bottomDiscripPain); canvas.drawText(landText[3] ,excursion + XPoint + (landWidth * 4) +(landAmong + textWidth(landText[0],26,bottomDiscripPain))+(landAmong + textWidth(landText[1],26,bottomDiscripPain))+(landAmong + textWidth(landText[2],26,bottomDiscripPain))+((landAmong + textWidth(landText[3],26,bottomDiscripPain))/2) ,landY +8,bottomDiscripPain); } private int landWidth = 60; private int landAmong = 60; private int excursion = -14; // land文字向x方向的偏移量 private float landY; private String [] landText = {"正常","带病运行","故障","关机"}; private float dipToPx(float dip) { float density = getContext().getResources().getDisplayMetrics().density; return (int)(dip * density + 0.5f * (dip >= 0 ? 1 : -1)); } public void setHeight(int height) { // 设置柱状高度 this.height = height; } public void setText(List<String> text) { // 设置底部标题 this.text = text; this.invalidate(); } public void setInfos(List<RunStatusBean> infos) { // 设置info this.infos = infos; this.invalidate(); } private float textWidth(String string, int size, Paint paint){ paint.setTextSize(size); float textWidth =paint.measureText(string + ""); return textWidth; }}
阅读全文
0 0
- Android绘制学习——基础形状
- android自定义View学习1——绘制基础
- 自定义View ——Canvas之绘制基本形状
- Android官网培训课:绘制形状
- Android绘制机制Paint基础学习
- Qt学习——不规则窗体形状
- Qt学习——不规则窗体形状 .
- Qt学习——不规则窗体形状
- opencv学习——常见滤波器形状
- 第二课 protel学习系列——原理图的绘制&PCB绘制基础
- 【Android】の基础——布局优化和过度绘制
- OpenCV学习第八篇:绘制形状和文字
- Android Training - 使用OpenGL ES(3) - 绘制形状
- Android Training - 使用OpenGL ES(3) - 绘制形状
- 使用Android OpenGL ES 2.0绘图之三:绘制形状
- Android菜鸟练习第二十课 xml绘制形状
- Android自定义View(五)_Canvas之绘制基本形状
- <Win32_9>SetWindowRgn函数的应用——绘制个性化形状的窗口
- vue2.0下axios实现跨域踩的坑
- AndroidStudio 混淆打包
- hdu1879 继续畅通工程 最小生成树
- 用户的邮件激活
- C指针笔记
- Android绘制学习——基础形状
- Dubbox 编译、安装
- 装饰模式(decorator)c++版本
- 全志R16调通USB接口的WIFI:RTL8188CU(分色排版)V1.0版本
- 聚类方法综述
- UML类图与类的关系详解
- 你是否真的会用==和equals
- 【转】jsp & servlet:forword 和 sendredirect
- messenger 的使用