前言
最近项目组要求实现一个柱状图,本想用第三方实现,但是领导说最近app瘦身,尽量不要采用第三方。于是,渣渣在查阅了 MPchart这个第三方后,自己写了一个自定义View实现对应需求。
效果图
实现功能:自定义View本质是draw绘制,我将功能切分了一下:
- 横坐标的名称
- 按比例实现柱状图的高低
- 横坐标轴和上边框的线
- 背景虚线
- 最低数据跟踪
- 没有数据显示
- 数字值显示
- 动态绘制
- 柱状图颜色变化
跟踪最小数据
float lineY = (startY + textHeight + maxBarHeight - (minBarHeight/totalTime * currentTime));
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.DKGRAY);
Path path = new Path();
path.moveTo(startX + 5 , lineY);
path.lineTo(itemWidth + widthSpace,lineY); // 起始宽度和默认柱子间距
PathEffect effects = new DashPathEffect(new float[]{15,15},2);
paint.setPathEffect(effects);
canvas.drawPath(path,paint);
画背景和坐标线
// 画下边框
Paint paint2 = new Paint();
paint2.setStyle(Paint.Style.STROKE);
paint2.setColor(Color.BLACK);
paint2.setStrokeWidth((float)2.0);
canvas.drawLine(startX, bottom, itemWidth, bottom, paint2);
// 计算虚线位置
float high1 = bottom-(1*(bottom-startY)/5);
float high2 = bottom-(2*(bottom-startY)/5);
float high3 = bottom-(3*(bottom-startY)/5);
float high4 = bottom-(4*(bottom-startY)/5);
float high5 = bottom-(5*(bottom-startY)/5);
// 画背景虚线
Paint painth1 = new Paint();
painth1.setStyle(Paint.Style.STROKE);
painth1.setColor(Color.BLUE);
painth1.setStrokeWidth((float)1.0);
canvas.drawLine(startX, high1, itemWidth, high1, painth1);
canvas.drawLine(startX, high2, itemWidth, high2, painth1);
canvas.drawLine(startX, high3, itemWidth, high3, painth1);
canvas.drawLine(startX, high4, itemWidth, high4, painth1);
canvas.drawLine(startX, high5, itemWidth, high5, painth1);
绘制横坐标名称
RectF textRectF = new RectF();
float subTitleLeft = left + i * barWidth;
float subTitleTop = startY + textHeight + maxBarHeight;
float subTitleRight = left + (i + 1) * barWidth;
float subTitleBottom = startY + textHeight + maxBarHeight + textHeight;
textRectF.set(subTitleLeft, subTitleTop, subTitleRight, subTitleBottom);
drawText(canvas, textRectF, mList.get(i).subTitle, mList.get(i).color);
绘制坐标数据
// 画num
RectF numRectF = new RectF();
float numLeft = left + i * barWidth;
// barHeight柱子的高度
float numTop = (startY + maxBarHeight) - barHeight;
float numRight = left + (i + 1) * barWidth;
float numBottom = (startY + textHeight + maxBarHeight) - barHeight;
numRectF.set(numLeft, numTop, numRight, numBottom);
drawText(canvas, numRectF, String.valueOf(mList.get(i).num), mList.get(i).color);
left += barWidth;
布局引用
<com.example.chartdemo.BarGraphView
android:id="@+id/bargraphview"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="310dp" />